etc
This commit is contained in:
parent
2187943124
commit
75ba8b6f4a
|
|
@ -5,7 +5,7 @@ option(CS_MIDI_BLE "Enable BLE MIDI interface (BTstack)" ON)
|
||||||
option(CS_MIDI_USB "Enable USB MIDI interface (TinyUSB)" OFF)
|
option(CS_MIDI_USB "Enable USB MIDI interface (TinyUSB)" OFF)
|
||||||
option(CS_MIDI_SERIAL "Enable Serial MIDI interface (UART)" OFF)
|
option(CS_MIDI_SERIAL "Enable Serial MIDI interface (UART)" OFF)
|
||||||
option(CS_MIDI_APPLEMIDI "Enable AppleMIDI interface (RTP-MIDI over WiFi)" OFF)
|
option(CS_MIDI_APPLEMIDI "Enable AppleMIDI interface (RTP-MIDI over WiFi)" OFF)
|
||||||
option(CS_MIDI_HID_MOUSE "Advertise as HID mouse for BLE auto-reconnect" OFF)
|
option(CS_MIDI_HID_KEYBOARD "HID keyboard + Battery Service for BLE auto-reconnect" OFF)
|
||||||
|
|
||||||
# Core sources — always compiled
|
# Core sources — always compiled
|
||||||
set(CS_MIDI_CORE_SOURCES
|
set(CS_MIDI_CORE_SOURCES
|
||||||
|
|
@ -80,7 +80,7 @@ target_compile_definitions(cs_midi PUBLIC
|
||||||
$<$<BOOL:${CS_MIDI_USB}>:CS_MIDI_USB=1>
|
$<$<BOOL:${CS_MIDI_USB}>:CS_MIDI_USB=1>
|
||||||
$<$<BOOL:${CS_MIDI_SERIAL}>:CS_MIDI_SERIAL=1>
|
$<$<BOOL:${CS_MIDI_SERIAL}>:CS_MIDI_SERIAL=1>
|
||||||
$<$<BOOL:${CS_MIDI_APPLEMIDI}>:CS_MIDI_APPLEMIDI=1>
|
$<$<BOOL:${CS_MIDI_APPLEMIDI}>:CS_MIDI_APPLEMIDI=1>
|
||||||
$<$<BOOL:${CS_MIDI_HID_MOUSE}>:CS_MIDI_HID_MOUSE=1>
|
$<$<BOOL:${CS_MIDI_HID_KEYBOARD}>:CS_MIDI_HID_KEYBOARD=1>
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(cs_midi
|
target_link_libraries(cs_midi
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,15 @@ namespace cs::midi_ble_btstack {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
#ifdef CS_MIDI_HID_MOUSE
|
#ifdef CS_MIDI_HID_KEYBOARD
|
||||||
uint8_t adv_data[] {
|
uint8_t adv_data[] {
|
||||||
// Flags general discoverable
|
// Flags general discoverable
|
||||||
0x02, BLUETOOTH_DATA_TYPE_FLAGS, 0x06,
|
0x02, BLUETOOTH_DATA_TYPE_FLAGS, 0x06,
|
||||||
// HID Service UUID (16-bit)
|
// HID Service UUID (16-bit)
|
||||||
0x03, BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS,
|
0x03, BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS,
|
||||||
0x12, 0x18,
|
0x12, 0x18,
|
||||||
// Appearance: Mouse (0x03C2)
|
// Appearance: Keyboard (0x03C1)
|
||||||
0x03, BLUETOOTH_DATA_TYPE_APPEARANCE, 0xC2, 0x03,
|
0x03, BLUETOOTH_DATA_TYPE_APPEARANCE, 0xC1, 0x03,
|
||||||
// MIDI Service UUID (128-bit)
|
// MIDI Service UUID (128-bit)
|
||||||
0x11, BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS,
|
0x11, BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS,
|
||||||
0x00, 0xc7, 0xc4, 0x4e, 0xe3, 0x6c, 0x51, 0xa7, 0x33, 0x4b, 0xe8, 0xed,
|
0x00, 0xc7, 0xc4, 0x4e, 0xe3, 0x6c, 0x51, 0xa7, 0x33, 0x4b, 0xe8, 0xed,
|
||||||
|
|
@ -42,7 +42,7 @@ uint8_t adv_rsp_data[LE_ADVERTISING_DATA_SIZE] {
|
||||||
' ', 'M', 'I', 'D', 'I'};
|
' ', 'M', 'I', 'D', 'I'};
|
||||||
uint8_t adv_rsp_data_len() { return adv_rsp_data[0] + 1; }
|
uint8_t adv_rsp_data_len() { return adv_rsp_data[0] + 1; }
|
||||||
|
|
||||||
#ifdef CS_MIDI_HID_MOUSE
|
#ifdef CS_MIDI_HID_KEYBOARD
|
||||||
void set_adv_connection_interval(uint16_t, uint16_t) {}
|
void set_adv_connection_interval(uint16_t, uint16_t) {}
|
||||||
#else
|
#else
|
||||||
void set_adv_connection_interval(uint16_t min_itvl, uint16_t max_itvl) {
|
void set_adv_connection_interval(uint16_t min_itvl, uint16_t max_itvl) {
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,10 @@
|
||||||
|
|
||||||
#include "../BLEAPI.hpp"
|
#include "../BLEAPI.hpp"
|
||||||
#include "advertising.hpp"
|
#include "advertising.hpp"
|
||||||
#ifdef CS_MIDI_HID_MOUSE
|
#ifdef CS_MIDI_HID_KEYBOARD
|
||||||
#include "gatt_midi_hog.h"
|
#include "gatt_midi_hog.h"
|
||||||
#include <ble/gatt-service/hids_device.h>
|
#include <ble/gatt-service/hids_device.h>
|
||||||
|
#include <ble/gatt-service/battery_service_server.h>
|
||||||
#else
|
#else
|
||||||
#include "gatt_midi.h"
|
#include "gatt_midi.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -36,34 +37,31 @@ BLESettings settings;
|
||||||
btstack_packet_callback_registration_t hci_event_callback_registration;
|
btstack_packet_callback_registration_t hci_event_callback_registration;
|
||||||
btstack_packet_callback_registration_t sm_event_callback_registration;
|
btstack_packet_callback_registration_t sm_event_callback_registration;
|
||||||
|
|
||||||
#ifdef CS_MIDI_HID_MOUSE
|
#ifdef CS_MIDI_HID_KEYBOARD
|
||||||
const uint8_t hid_descriptor_mouse[] = {
|
const uint8_t hid_descriptor_keyboard[] = {
|
||||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||||
0x09, 0x02, // Usage (Mouse)
|
0x09, 0x06, // Usage (Keyboard)
|
||||||
0xa1, 0x01, // Collection (Application)
|
0xa1, 0x01, // Collection (Application)
|
||||||
0x85, 0x01, // Report ID 1
|
0x85, 0x01, // Report ID 1
|
||||||
0x09, 0x01, // Usage (Pointer)
|
0x05, 0x07, // Usage Page (Keyboard/Keypad)
|
||||||
0xa1, 0x00, // Collection (Physical)
|
0x19, 0xe0, // Usage Minimum (Left Control)
|
||||||
0x05, 0x09, // Usage Page (Buttons)
|
0x29, 0xe7, // Usage Maximum (Right GUI)
|
||||||
0x19, 0x01, // Usage Minimum (1)
|
0x15, 0x00, // Logical Minimum (0)
|
||||||
0x29, 0x03, // Usage Maximum (3)
|
0x25, 0x01, // Logical Maximum (1)
|
||||||
0x15, 0x00, // Logical Minimum (0)
|
0x75, 0x01, // Report Size (1)
|
||||||
0x25, 0x01, // Logical Maximum (1)
|
0x95, 0x08, // Report Count (8)
|
||||||
0x95, 0x03, // Report Count (3)
|
0x81, 0x02, // Input (Data,Var,Abs) — modifiers
|
||||||
0x75, 0x01, // Report Size (1)
|
0x95, 0x01, // Report Count (1)
|
||||||
0x81, 0x02, // Input (Data,Var,Abs)
|
0x75, 0x08, // Report Size (8)
|
||||||
0x95, 0x01, // Report Count (1)
|
0x81, 0x01, // Input (Const) — reserved
|
||||||
0x75, 0x05, // Report Size (5)
|
0x95, 0x06, // Report Count (6)
|
||||||
0x81, 0x03, // Input (Const,Var,Abs) — padding
|
0x75, 0x08, // Report Size (8)
|
||||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
0x15, 0x00, // Logical Minimum (0)
|
||||||
0x09, 0x30, // Usage (X)
|
0x26, 0xff, 0x00, // Logical Maximum (255)
|
||||||
0x09, 0x31, // Usage (Y)
|
0x05, 0x07, // Usage Page (Keyboard/Keypad)
|
||||||
0x15, 0x81, // Logical Minimum (-127)
|
0x19, 0x00, // Usage Minimum (0)
|
||||||
0x25, 0x7f, // Logical Maximum (127)
|
0x29, 0xff, // Usage Maximum (255)
|
||||||
0x75, 0x08, // Report Size (8)
|
0x81, 0x00, // Input (Data,Ary,Abs) — 6KRO keycodes
|
||||||
0x95, 0x02, // Report Count (2)
|
|
||||||
0x81, 0x06, // Input (Data,Var,Rel)
|
|
||||||
0xc0, // End Collection
|
|
||||||
0xc0 // End Collection
|
0xc0 // End Collection
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -73,7 +71,6 @@ constexpr uint16_t gap_device_name_handle =
|
||||||
void hid_packet_handler(uint8_t packet_type, uint16_t, uint8_t *packet, uint16_t) {
|
void hid_packet_handler(uint8_t packet_type, uint16_t, uint8_t *packet, uint16_t) {
|
||||||
if (packet_type != HCI_EVENT_PACKET) return;
|
if (packet_type != HCI_EVENT_PACKET) return;
|
||||||
if (hci_event_packet_get_type(packet) != HCI_EVENT_HIDS_META) return;
|
if (hci_event_packet_get_type(packet) != HCI_EVENT_HIDS_META) return;
|
||||||
// Accept HID events but never send mouse reports
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -225,7 +222,7 @@ uint16_t att_read_callback([[maybe_unused]] hci_con_handle_t connection_handle,
|
||||||
[[maybe_unused]] uint16_t offset,
|
[[maybe_unused]] uint16_t offset,
|
||||||
[[maybe_unused]] uint8_t *buffer,
|
[[maybe_unused]] uint8_t *buffer,
|
||||||
[[maybe_unused]] uint16_t buffer_size) {
|
[[maybe_unused]] uint16_t buffer_size) {
|
||||||
#ifdef CS_MIDI_HID_MOUSE
|
#ifdef CS_MIDI_HID_KEYBOARD
|
||||||
if (att_handle == gap_device_name_handle) {
|
if (att_handle == gap_device_name_handle) {
|
||||||
const char *name = settings.device_name;
|
const char *name = settings.device_name;
|
||||||
auto len = static_cast<uint16_t>(std::strlen(name));
|
auto len = static_cast<uint16_t>(std::strlen(name));
|
||||||
|
|
@ -294,9 +291,10 @@ void le_midi_setup(const BLESettings &ble_settings) {
|
||||||
SM_AUTHREQ_BONDING);
|
SM_AUTHREQ_BONDING);
|
||||||
// setup ATT server
|
// setup ATT server
|
||||||
att_server_init(profile_data, att_read_callback, att_write_callback);
|
att_server_init(profile_data, att_read_callback, att_write_callback);
|
||||||
#ifdef CS_MIDI_HID_MOUSE
|
#ifdef CS_MIDI_HID_KEYBOARD
|
||||||
hids_device_init(0, hid_descriptor_mouse, sizeof(hid_descriptor_mouse));
|
hids_device_init(0, hid_descriptor_keyboard, sizeof(hid_descriptor_keyboard));
|
||||||
hids_device_register_packet_handler(hid_packet_handler);
|
hids_device_register_packet_handler(hid_packet_handler);
|
||||||
|
battery_service_server_init(100);
|
||||||
#endif
|
#endif
|
||||||
// setup advertisements
|
// setup advertisements
|
||||||
le_midi_setup_adv(ble_settings);
|
le_midi_setup_adv(ble_settings);
|
||||||
|
|
@ -368,4 +366,10 @@ void notify(BLEConnectionHandle conn_handle,
|
||||||
DEBUGREF("all done " << micros() - t0);
|
DEBUGREF("all done " << micros() - t0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CS_MIDI_HID_KEYBOARD
|
||||||
|
void set_battery_level(uint8_t percent) {
|
||||||
|
battery_service_server_set_battery_value(percent);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace cs::midi_ble_btstack
|
} // namespace cs::midi_ble_btstack
|
||||||
|
|
@ -8,4 +8,8 @@ bool init(MIDIBLEInstance &instance, BLESettings settings);
|
||||||
void notify(BLEConnectionHandle conn_handle,
|
void notify(BLEConnectionHandle conn_handle,
|
||||||
BLECharacteristicHandle char_handle, BLEDataView data);
|
BLECharacteristicHandle char_handle, BLEDataView data);
|
||||||
|
|
||||||
|
#ifdef CS_MIDI_HID_KEYBOARD
|
||||||
|
void set_battery_level(uint8_t percent);
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace cs::midi_ble_btstack
|
} // namespace cs::midi_ble_btstack
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ CHARACTERISTIC, GATT_DATABASE_HASH, READ,
|
||||||
|
|
||||||
PRIMARY_SERVICE, GAP_SERVICE
|
PRIMARY_SERVICE, GAP_SERVICE
|
||||||
CHARACTERISTIC, GAP_DEVICE_NAME, READ | DYNAMIC,
|
CHARACTERISTIC, GAP_DEVICE_NAME, READ | DYNAMIC,
|
||||||
// 0x03C2 = HID Mouse
|
// 0x03C1 = HID Keyboard
|
||||||
CHARACTERISTIC, GAP_APPEARANCE, READ, C2 03
|
CHARACTERISTIC, GAP_APPEARANCE, READ, C1 03
|
||||||
|
|
||||||
// MIDI Service
|
// MIDI Service
|
||||||
PRIMARY_SERVICE, 03B80E5A-EDE8-4B33-A751-6CE34EC4C700
|
PRIMARY_SERVICE, 03B80E5A-EDE8-4B33-A751-6CE34EC4C700
|
||||||
|
|
@ -12,3 +12,6 @@ CHARACTERISTIC, 7772E5DB-3868-4112-A1A9-F2669D106BF3, READ | WRITE_WITHOUT_RESPO
|
||||||
|
|
||||||
// HID Service
|
// HID Service
|
||||||
#import <hids.gatt>
|
#import <hids.gatt>
|
||||||
|
|
||||||
|
// Battery Service
|
||||||
|
#import <battery_service.gatt>
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,19 @@
|
||||||
// Generated from gatt_midi_hog.gatt — MIDI + HoG Mouse combined GATT database
|
|
||||||
// Regenerate: compile_gatt.py gatt_midi_hog.gatt gatt_midi_hog.h
|
// clang-format off
|
||||||
|
// gatt_midi_hog.h generated from gatt_midi_hog.gatt for BTstack
|
||||||
|
// it needs to be regenerated when the .gatt file is updated.
|
||||||
|
|
||||||
|
// To generate gatt_midi_hog.h:
|
||||||
|
// compile_gatt.py gatt_midi_hog.gatt gatt_midi_hog.h
|
||||||
|
|
||||||
// att db format version 1
|
// att db format version 1
|
||||||
|
|
||||||
// binary attribute representation:
|
// binary attribute representation:
|
||||||
// - size in bytes (16), flags(16), handle (16), uuid (16/128), value(...)
|
// - size in bytes (16), flags(16), handle (16), uuid (16/128), value(...)
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Reference: https://en.cppreference.com/w/cpp/feature_test
|
||||||
#if __cplusplus >= 200704L
|
#if __cplusplus >= 200704L
|
||||||
constexpr
|
constexpr
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -19,89 +26,133 @@ const uint8_t profile_data[] =
|
||||||
0x0a, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x28, 0x01, 0x18,
|
0x0a, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x28, 0x01, 0x18,
|
||||||
// 0x0002 CHARACTERISTIC-GATT_DATABASE_HASH - READ
|
// 0x0002 CHARACTERISTIC-GATT_DATABASE_HASH - READ
|
||||||
0x0d, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x28, 0x02, 0x03, 0x00, 0x2a, 0x2b,
|
0x0d, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x28, 0x02, 0x03, 0x00, 0x2a, 0x2b,
|
||||||
// 0x0003 VALUE CHARACTERISTIC-GATT_DATABASE_HASH - READ
|
// 0x0003 VALUE CHARACTERISTIC-GATT_DATABASE_HASH - READ -''
|
||||||
0x18, 0x00, 0x02, 0x00, 0x03, 0x00, 0x2a, 0x2b, 0xce, 0x0f, 0xc6, 0xd0, 0xa1, 0x9c, 0xd7, 0xa2, 0x98, 0xad, 0x7d, 0x4c, 0x9c, 0x85, 0xed, 0x81,
|
// READ_ANYBODY
|
||||||
|
0x18, 0x00, 0x02, 0x00, 0x03, 0x00, 0x2a, 0x2b, 0xab, 0x5a, 0x3b, 0x8c, 0x3f, 0x95, 0x12, 0x5d, 0x5a, 0xa5, 0x27, 0xb7, 0x75, 0x27, 0xfc, 0x2b,
|
||||||
// 0x0004 PRIMARY_SERVICE-GAP_SERVICE
|
// 0x0004 PRIMARY_SERVICE-GAP_SERVICE
|
||||||
0x0a, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x28, 0x00, 0x18,
|
0x0a, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x28, 0x00, 0x18,
|
||||||
// 0x0005 CHARACTERISTIC-GAP_DEVICE_NAME - READ | DYNAMIC
|
// 0x0005 CHARACTERISTIC-GAP_DEVICE_NAME - READ | DYNAMIC
|
||||||
0x0d, 0x00, 0x02, 0x00, 0x05, 0x00, 0x03, 0x28, 0x02, 0x06, 0x00, 0x00, 0x2a,
|
0x0d, 0x00, 0x02, 0x00, 0x05, 0x00, 0x03, 0x28, 0x02, 0x06, 0x00, 0x00, 0x2a,
|
||||||
// 0x0006 VALUE CHARACTERISTIC-GAP_DEVICE_NAME - READ | DYNAMIC
|
// 0x0006 VALUE CHARACTERISTIC-GAP_DEVICE_NAME - READ | DYNAMIC
|
||||||
|
// READ_ANYBODY
|
||||||
0x08, 0x00, 0x02, 0x01, 0x06, 0x00, 0x00, 0x2a,
|
0x08, 0x00, 0x02, 0x01, 0x06, 0x00, 0x00, 0x2a,
|
||||||
// 0x0007 CHARACTERISTIC-GAP_APPEARANCE - READ - Mouse (0x03C2)
|
// 0x03C1 = HID Keyboard
|
||||||
|
// 0x0007 CHARACTERISTIC-GAP_APPEARANCE - READ
|
||||||
0x0d, 0x00, 0x02, 0x00, 0x07, 0x00, 0x03, 0x28, 0x02, 0x08, 0x00, 0x01, 0x2a,
|
0x0d, 0x00, 0x02, 0x00, 0x07, 0x00, 0x03, 0x28, 0x02, 0x08, 0x00, 0x01, 0x2a,
|
||||||
// 0x0008 VALUE CHARACTERISTIC-GAP_APPEARANCE - READ
|
// 0x0008 VALUE CHARACTERISTIC-GAP_APPEARANCE - READ -'C1 03'
|
||||||
0x0a, 0x00, 0x02, 0x00, 0x08, 0x00, 0x01, 0x2a, 0xC2, 0x03,
|
// READ_ANYBODY
|
||||||
|
0x0a, 0x00, 0x02, 0x00, 0x08, 0x00, 0x01, 0x2a, 0xC1, 0x03,
|
||||||
// MIDI Service
|
// MIDI Service
|
||||||
// 0x0009 PRIMARY_SERVICE-03B80E5A-EDE8-4B33-A751-6CE34EC4C700
|
// 0x0009 PRIMARY_SERVICE-03B80E5A-EDE8-4B33-A751-6CE34EC4C700
|
||||||
0x18, 0x00, 0x02, 0x00, 0x09, 0x00, 0x00, 0x28, 0x00, 0xc7, 0xc4, 0x4e, 0xe3, 0x6c, 0x51, 0xa7, 0x33, 0x4b, 0xe8, 0xed, 0x5a, 0x0e, 0xb8, 0x03,
|
0x18, 0x00, 0x02, 0x00, 0x09, 0x00, 0x00, 0x28, 0x00, 0xc7, 0xc4, 0x4e, 0xe3, 0x6c, 0x51, 0xa7, 0x33, 0x4b, 0xe8, 0xed, 0x5a, 0x0e, 0xb8, 0x03,
|
||||||
// 0x000a CHARACTERISTIC-7772E5DB-3868-4112-A1A9-F2669D106BF3 - READ | WRITE_WITHOUT_RESPONSE | NOTIFY | DYNAMIC
|
// 0x000a CHARACTERISTIC-7772E5DB-3868-4112-A1A9-F2669D106BF3 - READ | WRITE_WITHOUT_RESPONSE | NOTIFY | DYNAMIC
|
||||||
0x1b, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x03, 0x28, 0x16, 0x0b, 0x00, 0xf3, 0x6b, 0x10, 0x9d, 0x66, 0xf2, 0xa9, 0xa1, 0x12, 0x41, 0x68, 0x38, 0xdb, 0xe5, 0x72, 0x77,
|
0x1b, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x03, 0x28, 0x16, 0x0b, 0x00, 0xf3, 0x6b, 0x10, 0x9d, 0x66, 0xf2, 0xa9, 0xa1, 0x12, 0x41, 0x68, 0x38, 0xdb, 0xe5, 0x72, 0x77,
|
||||||
// 0x000b VALUE CHARACTERISTIC-7772E5DB-3868-4112-A1A9-F2669D106BF3 - READ | WRITE_WITHOUT_RESPONSE | NOTIFY | DYNAMIC
|
// 0x000b VALUE CHARACTERISTIC-7772E5DB-3868-4112-A1A9-F2669D106BF3 - READ | WRITE_WITHOUT_RESPONSE | NOTIFY | DYNAMIC
|
||||||
|
// READ_ANYBODY, WRITE_ANYBODY
|
||||||
0x16, 0x00, 0x06, 0x03, 0x0b, 0x00, 0xf3, 0x6b, 0x10, 0x9d, 0x66, 0xf2, 0xa9, 0xa1, 0x12, 0x41, 0x68, 0x38, 0xdb, 0xe5, 0x72, 0x77,
|
0x16, 0x00, 0x06, 0x03, 0x0b, 0x00, 0xf3, 0x6b, 0x10, 0x9d, 0x66, 0xf2, 0xa9, 0xa1, 0x12, 0x41, 0x68, 0x38, 0xdb, 0xe5, 0x72, 0x77,
|
||||||
// 0x000c CLIENT_CHARACTERISTIC_CONFIGURATION
|
// 0x000c CLIENT_CHARACTERISTIC_CONFIGURATION
|
||||||
|
// READ_ANYBODY, WRITE_ANYBODY
|
||||||
0x0a, 0x00, 0x0e, 0x01, 0x0c, 0x00, 0x02, 0x29, 0x00, 0x00,
|
0x0a, 0x00, 0x0e, 0x01, 0x0c, 0x00, 0x02, 0x29, 0x00, 0x00,
|
||||||
|
// HID Service
|
||||||
|
|
||||||
// HID Service (hids.gatt)
|
|
||||||
|
// #import <hids.gatt> -- BEGIN
|
||||||
|
// Specification Type org.bluetooth.service.human_interface_device
|
||||||
|
// https://www.bluetooth.com/api/gatt/xmlfile?xmlFileName=org.bluetooth.service.human_interface_device.xml
|
||||||
|
// Human Interface Device 1812
|
||||||
// 0x000d PRIMARY_SERVICE-ORG_BLUETOOTH_SERVICE_HUMAN_INTERFACE_DEVICE
|
// 0x000d PRIMARY_SERVICE-ORG_BLUETOOTH_SERVICE_HUMAN_INTERFACE_DEVICE
|
||||||
0x0a, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x00, 0x28, 0x12, 0x18,
|
0x0a, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x00, 0x28, 0x12, 0x18,
|
||||||
// 0x000e CHARACTERISTIC-PROTOCOL_MODE - DYNAMIC | READ | WRITE_WITHOUT_RESPONSE
|
// 0x000e CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_PROTOCOL_MODE - DYNAMIC | READ | WRITE_WITHOUT_RESPONSE
|
||||||
0x0d, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x03, 0x28, 0x06, 0x0f, 0x00, 0x4e, 0x2a,
|
0x0d, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x03, 0x28, 0x06, 0x0f, 0x00, 0x4e, 0x2a,
|
||||||
// 0x000f VALUE CHARACTERISTIC-PROTOCOL_MODE
|
// 0x000f VALUE CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_PROTOCOL_MODE - DYNAMIC | READ | WRITE_WITHOUT_RESPONSE
|
||||||
|
// READ_ANYBODY, WRITE_ANYBODY
|
||||||
0x08, 0x00, 0x06, 0x01, 0x0f, 0x00, 0x4e, 0x2a,
|
0x08, 0x00, 0x06, 0x01, 0x0f, 0x00, 0x4e, 0x2a,
|
||||||
// 0x0010 CHARACTERISTIC-REPORT (Input, ID=1) - DYNAMIC | READ | WRITE | NOTIFY | ENCRYPTION_KEY_SIZE_16
|
// 0x0010 CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_REPORT - DYNAMIC | READ | WRITE | NOTIFY | ENCRYPTION_KEY_SIZE_16
|
||||||
0x0d, 0x00, 0x02, 0x00, 0x10, 0x00, 0x03, 0x28, 0x1a, 0x11, 0x00, 0x4d, 0x2a,
|
0x0d, 0x00, 0x02, 0x00, 0x10, 0x00, 0x03, 0x28, 0x1a, 0x11, 0x00, 0x4d, 0x2a,
|
||||||
// 0x0011 VALUE CHARACTERISTIC-REPORT
|
// 0x0011 VALUE CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_REPORT - DYNAMIC | READ | WRITE | NOTIFY | ENCRYPTION_KEY_SIZE_16
|
||||||
|
// READ_ENCRYPTED, WRITE_ENCRYPTED, ENCRYPTION_KEY_SIZE=16
|
||||||
0x08, 0x00, 0x0b, 0xf5, 0x11, 0x00, 0x4d, 0x2a,
|
0x08, 0x00, 0x0b, 0xf5, 0x11, 0x00, 0x4d, 0x2a,
|
||||||
// 0x0012 CLIENT_CHARACTERISTIC_CONFIGURATION
|
// 0x0012 CLIENT_CHARACTERISTIC_CONFIGURATION
|
||||||
|
// READ_ANYBODY, WRITE_ENCRYPTED, ENCRYPTION_KEY_SIZE=16
|
||||||
0x0a, 0x00, 0x0f, 0xf1, 0x12, 0x00, 0x02, 0x29, 0x00, 0x00,
|
0x0a, 0x00, 0x0f, 0xf1, 0x12, 0x00, 0x02, 0x29, 0x00, 0x00,
|
||||||
// 0x0013 REPORT_REFERENCE - Report ID=1, Type=Input(1)
|
// fixed report id = 1, type = Input (1)
|
||||||
|
// 0x0013 REPORT_REFERENCE-READ-1-1
|
||||||
0x0a, 0x00, 0x02, 0x00, 0x13, 0x00, 0x08, 0x29, 0x1, 0x1,
|
0x0a, 0x00, 0x02, 0x00, 0x13, 0x00, 0x08, 0x29, 0x1, 0x1,
|
||||||
// 0x0014 CHARACTERISTIC-REPORT (Output, ID=2) - DYNAMIC | READ | WRITE | WRITE_WITHOUT_RESPONSE | ENCRYPTION_KEY_SIZE_16
|
// 0x0014 CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_REPORT - DYNAMIC | READ | WRITE | WRITE_WITHOUT_RESPONSE | ENCRYPTION_KEY_SIZE_16
|
||||||
0x0d, 0x00, 0x02, 0x00, 0x14, 0x00, 0x03, 0x28, 0x0e, 0x15, 0x00, 0x4d, 0x2a,
|
0x0d, 0x00, 0x02, 0x00, 0x14, 0x00, 0x03, 0x28, 0x0e, 0x15, 0x00, 0x4d, 0x2a,
|
||||||
// 0x0015 VALUE CHARACTERISTIC-REPORT
|
// 0x0015 VALUE CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_REPORT - DYNAMIC | READ | WRITE | WRITE_WITHOUT_RESPONSE | ENCRYPTION_KEY_SIZE_16
|
||||||
|
// READ_ENCRYPTED, WRITE_ENCRYPTED, ENCRYPTION_KEY_SIZE=16
|
||||||
0x08, 0x00, 0x0f, 0xf5, 0x15, 0x00, 0x4d, 0x2a,
|
0x08, 0x00, 0x0f, 0xf5, 0x15, 0x00, 0x4d, 0x2a,
|
||||||
// 0x0016 REPORT_REFERENCE - Report ID=2, Type=Output(2)
|
// fixed report id = 2, type = Output (2)
|
||||||
|
// 0x0016 REPORT_REFERENCE-READ-2-2
|
||||||
0x0a, 0x00, 0x02, 0x00, 0x16, 0x00, 0x08, 0x29, 0x2, 0x2,
|
0x0a, 0x00, 0x02, 0x00, 0x16, 0x00, 0x08, 0x29, 0x2, 0x2,
|
||||||
// 0x0017 CHARACTERISTIC-REPORT (Feature, ID=3) - DYNAMIC | READ | WRITE | ENCRYPTION_KEY_SIZE_16
|
// 0x0017 CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_REPORT - DYNAMIC | READ | WRITE | ENCRYPTION_KEY_SIZE_16
|
||||||
0x0d, 0x00, 0x02, 0x00, 0x17, 0x00, 0x03, 0x28, 0x0a, 0x18, 0x00, 0x4d, 0x2a,
|
0x0d, 0x00, 0x02, 0x00, 0x17, 0x00, 0x03, 0x28, 0x0a, 0x18, 0x00, 0x4d, 0x2a,
|
||||||
// 0x0018 VALUE CHARACTERISTIC-REPORT
|
// 0x0018 VALUE CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_REPORT - DYNAMIC | READ | WRITE | ENCRYPTION_KEY_SIZE_16
|
||||||
|
// READ_ENCRYPTED, WRITE_ENCRYPTED, ENCRYPTION_KEY_SIZE=16
|
||||||
0x08, 0x00, 0x0b, 0xf5, 0x18, 0x00, 0x4d, 0x2a,
|
0x08, 0x00, 0x0b, 0xf5, 0x18, 0x00, 0x4d, 0x2a,
|
||||||
// 0x0019 REPORT_REFERENCE - Report ID=3, Type=Feature(3)
|
// fixed report id = 3, type = Feature (3)
|
||||||
|
// 0x0019 REPORT_REFERENCE-READ-3-3
|
||||||
0x0a, 0x00, 0x02, 0x00, 0x19, 0x00, 0x08, 0x29, 0x3, 0x3,
|
0x0a, 0x00, 0x02, 0x00, 0x19, 0x00, 0x08, 0x29, 0x3, 0x3,
|
||||||
// 0x001a CHARACTERISTIC-REPORT_MAP - DYNAMIC | READ
|
// 0x001a CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_REPORT_MAP - DYNAMIC | READ
|
||||||
0x0d, 0x00, 0x02, 0x00, 0x1a, 0x00, 0x03, 0x28, 0x02, 0x1b, 0x00, 0x4b, 0x2a,
|
0x0d, 0x00, 0x02, 0x00, 0x1a, 0x00, 0x03, 0x28, 0x02, 0x1b, 0x00, 0x4b, 0x2a,
|
||||||
// 0x001b VALUE CHARACTERISTIC-REPORT_MAP
|
// 0x001b VALUE CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_REPORT_MAP - DYNAMIC | READ
|
||||||
|
// READ_ANYBODY
|
||||||
0x08, 0x00, 0x02, 0x01, 0x1b, 0x00, 0x4b, 0x2a,
|
0x08, 0x00, 0x02, 0x01, 0x1b, 0x00, 0x4b, 0x2a,
|
||||||
// 0x001c CHARACTERISTIC-BOOT_KEYBOARD_INPUT_REPORT - DYNAMIC | READ | WRITE | NOTIFY
|
// 0x001c CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_BOOT_KEYBOARD_INPUT_REPORT - DYNAMIC | READ | WRITE | NOTIFY
|
||||||
0x0d, 0x00, 0x02, 0x00, 0x1c, 0x00, 0x03, 0x28, 0x1a, 0x1d, 0x00, 0x22, 0x2a,
|
0x0d, 0x00, 0x02, 0x00, 0x1c, 0x00, 0x03, 0x28, 0x1a, 0x1d, 0x00, 0x22, 0x2a,
|
||||||
// 0x001d VALUE CHARACTERISTIC-BOOT_KEYBOARD_INPUT_REPORT
|
// 0x001d VALUE CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_BOOT_KEYBOARD_INPUT_REPORT - DYNAMIC | READ | WRITE | NOTIFY
|
||||||
|
// READ_ANYBODY, WRITE_ANYBODY
|
||||||
0x08, 0x00, 0x0a, 0x01, 0x1d, 0x00, 0x22, 0x2a,
|
0x08, 0x00, 0x0a, 0x01, 0x1d, 0x00, 0x22, 0x2a,
|
||||||
// 0x001e CLIENT_CHARACTERISTIC_CONFIGURATION
|
// 0x001e CLIENT_CHARACTERISTIC_CONFIGURATION
|
||||||
|
// READ_ANYBODY, WRITE_ANYBODY
|
||||||
0x0a, 0x00, 0x0e, 0x01, 0x1e, 0x00, 0x02, 0x29, 0x00, 0x00,
|
0x0a, 0x00, 0x0e, 0x01, 0x1e, 0x00, 0x02, 0x29, 0x00, 0x00,
|
||||||
// 0x001f CHARACTERISTIC-BOOT_KEYBOARD_OUTPUT_REPORT - DYNAMIC | READ | WRITE | WRITE_WITHOUT_RESPONSE
|
// 0x001f CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_BOOT_KEYBOARD_OUTPUT_REPORT - DYNAMIC | READ | WRITE | WRITE_WITHOUT_RESPONSE
|
||||||
0x0d, 0x00, 0x02, 0x00, 0x1f, 0x00, 0x03, 0x28, 0x0e, 0x20, 0x00, 0x32, 0x2a,
|
0x0d, 0x00, 0x02, 0x00, 0x1f, 0x00, 0x03, 0x28, 0x0e, 0x20, 0x00, 0x32, 0x2a,
|
||||||
// 0x0020 VALUE CHARACTERISTIC-BOOT_KEYBOARD_OUTPUT_REPORT
|
// 0x0020 VALUE CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_BOOT_KEYBOARD_OUTPUT_REPORT - DYNAMIC | READ | WRITE | WRITE_WITHOUT_RESPONSE
|
||||||
|
// READ_ANYBODY, WRITE_ANYBODY
|
||||||
0x08, 0x00, 0x0e, 0x01, 0x20, 0x00, 0x32, 0x2a,
|
0x08, 0x00, 0x0e, 0x01, 0x20, 0x00, 0x32, 0x2a,
|
||||||
// 0x0021 CHARACTERISTIC-BOOT_MOUSE_INPUT_REPORT - DYNAMIC | READ | WRITE | NOTIFY
|
// 0x0021 CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_BOOT_MOUSE_INPUT_REPORT - DYNAMIC | READ | WRITE | NOTIFY
|
||||||
0x0d, 0x00, 0x02, 0x00, 0x21, 0x00, 0x03, 0x28, 0x1a, 0x22, 0x00, 0x33, 0x2a,
|
0x0d, 0x00, 0x02, 0x00, 0x21, 0x00, 0x03, 0x28, 0x1a, 0x22, 0x00, 0x33, 0x2a,
|
||||||
// 0x0022 VALUE CHARACTERISTIC-BOOT_MOUSE_INPUT_REPORT
|
// 0x0022 VALUE CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_BOOT_MOUSE_INPUT_REPORT - DYNAMIC | READ | WRITE | NOTIFY
|
||||||
|
// READ_ANYBODY, WRITE_ANYBODY
|
||||||
0x08, 0x00, 0x0a, 0x01, 0x22, 0x00, 0x33, 0x2a,
|
0x08, 0x00, 0x0a, 0x01, 0x22, 0x00, 0x33, 0x2a,
|
||||||
// 0x0023 CLIENT_CHARACTERISTIC_CONFIGURATION
|
// 0x0023 CLIENT_CHARACTERISTIC_CONFIGURATION
|
||||||
|
// READ_ANYBODY, WRITE_ANYBODY
|
||||||
0x0a, 0x00, 0x0e, 0x01, 0x23, 0x00, 0x02, 0x29, 0x00, 0x00,
|
0x0a, 0x00, 0x0e, 0x01, 0x23, 0x00, 0x02, 0x29, 0x00, 0x00,
|
||||||
// 0x0024 CHARACTERISTIC-HID_INFORMATION - READ
|
// bcdHID = 0x101 (v1.0.1), bCountryCode 0, remote wakeable = 0 | normally connectable 2
|
||||||
|
// 0x0024 CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_HID_INFORMATION - READ
|
||||||
0x0d, 0x00, 0x02, 0x00, 0x24, 0x00, 0x03, 0x28, 0x02, 0x25, 0x00, 0x4a, 0x2a,
|
0x0d, 0x00, 0x02, 0x00, 0x24, 0x00, 0x03, 0x28, 0x02, 0x25, 0x00, 0x4a, 0x2a,
|
||||||
// 0x0025 VALUE CHARACTERISTIC-HID_INFORMATION - bcdHID=0x0101, country=0, flags=0x02
|
// 0x0025 VALUE CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_HID_INFORMATION - READ -'01 01 00 02'
|
||||||
|
// READ_ANYBODY
|
||||||
0x0c, 0x00, 0x02, 0x00, 0x25, 0x00, 0x4a, 0x2a, 0x01, 0x01, 0x00, 0x02,
|
0x0c, 0x00, 0x02, 0x00, 0x25, 0x00, 0x4a, 0x2a, 0x01, 0x01, 0x00, 0x02,
|
||||||
// 0x0026 CHARACTERISTIC-HID_CONTROL_POINT - DYNAMIC | WRITE_WITHOUT_RESPONSE
|
// 0x0026 CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_HID_CONTROL_POINT - DYNAMIC | WRITE_WITHOUT_RESPONSE
|
||||||
0x0d, 0x00, 0x02, 0x00, 0x26, 0x00, 0x03, 0x28, 0x04, 0x27, 0x00, 0x4c, 0x2a,
|
0x0d, 0x00, 0x02, 0x00, 0x26, 0x00, 0x03, 0x28, 0x04, 0x27, 0x00, 0x4c, 0x2a,
|
||||||
// 0x0027 VALUE CHARACTERISTIC-HID_CONTROL_POINT
|
// 0x0027 VALUE CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_HID_CONTROL_POINT - DYNAMIC | WRITE_WITHOUT_RESPONSE
|
||||||
|
// WRITE_ANYBODY
|
||||||
0x08, 0x00, 0x04, 0x01, 0x27, 0x00, 0x4c, 0x2a,
|
0x08, 0x00, 0x04, 0x01, 0x27, 0x00, 0x4c, 0x2a,
|
||||||
|
// #import <hids.gatt> -- END
|
||||||
|
// Battery Service
|
||||||
|
|
||||||
|
|
||||||
|
// #import <battery_service.gatt> -- BEGIN
|
||||||
|
// Specification Type org.bluetooth.service.battery_service
|
||||||
|
// https://www.bluetooth.com/api/gatt/xmlfile?xmlFileName=org.bluetooth.service.battery_service.xml
|
||||||
|
// Battery Service 180F
|
||||||
|
// 0x0028 PRIMARY_SERVICE-ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE
|
||||||
|
0x0a, 0x00, 0x02, 0x00, 0x28, 0x00, 0x00, 0x28, 0x0f, 0x18,
|
||||||
|
// 0x0029 CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL - DYNAMIC | READ | NOTIFY
|
||||||
|
0x0d, 0x00, 0x02, 0x00, 0x29, 0x00, 0x03, 0x28, 0x12, 0x2a, 0x00, 0x19, 0x2a,
|
||||||
|
// 0x002a VALUE CHARACTERISTIC-ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL - DYNAMIC | READ | NOTIFY
|
||||||
|
// READ_ANYBODY
|
||||||
|
0x08, 0x00, 0x02, 0x01, 0x2a, 0x00, 0x19, 0x2a,
|
||||||
|
// 0x002b CLIENT_CHARACTERISTIC_CONFIGURATION
|
||||||
|
// READ_ANYBODY, WRITE_ANYBODY
|
||||||
|
0x0a, 0x00, 0x0e, 0x01, 0x2b, 0x00, 0x02, 0x29, 0x00, 0x00,
|
||||||
|
// #import <battery_service.gatt> -- END
|
||||||
// END
|
// END
|
||||||
0x00, 0x00,
|
0x00, 0x00,
|
||||||
}; // total size 252 bytes
|
}; // total size 275 bytes
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -123,6 +174,10 @@ const uint8_t profile_data[] =
|
||||||
#define ATT_SERVICE_ORG_BLUETOOTH_SERVICE_HUMAN_INTERFACE_DEVICE_END_HANDLE 0x0027
|
#define ATT_SERVICE_ORG_BLUETOOTH_SERVICE_HUMAN_INTERFACE_DEVICE_END_HANDLE 0x0027
|
||||||
#define ATT_SERVICE_ORG_BLUETOOTH_SERVICE_HUMAN_INTERFACE_DEVICE_01_START_HANDLE 0x000d
|
#define ATT_SERVICE_ORG_BLUETOOTH_SERVICE_HUMAN_INTERFACE_DEVICE_01_START_HANDLE 0x000d
|
||||||
#define ATT_SERVICE_ORG_BLUETOOTH_SERVICE_HUMAN_INTERFACE_DEVICE_01_END_HANDLE 0x0027
|
#define ATT_SERVICE_ORG_BLUETOOTH_SERVICE_HUMAN_INTERFACE_DEVICE_01_END_HANDLE 0x0027
|
||||||
|
#define ATT_SERVICE_ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE_START_HANDLE 0x0028
|
||||||
|
#define ATT_SERVICE_ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE_END_HANDLE 0x002b
|
||||||
|
#define ATT_SERVICE_ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE_01_START_HANDLE 0x0028
|
||||||
|
#define ATT_SERVICE_ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE_01_END_HANDLE 0x002b
|
||||||
|
|
||||||
//
|
//
|
||||||
// list mapping between characteristics and handles
|
// list mapping between characteristics and handles
|
||||||
|
|
@ -145,3 +200,5 @@ const uint8_t profile_data[] =
|
||||||
#define ATT_CHARACTERISTIC_ORG_BLUETOOTH_CHARACTERISTIC_BOOT_MOUSE_INPUT_REPORT_01_CLIENT_CONFIGURATION_HANDLE 0x0023
|
#define ATT_CHARACTERISTIC_ORG_BLUETOOTH_CHARACTERISTIC_BOOT_MOUSE_INPUT_REPORT_01_CLIENT_CONFIGURATION_HANDLE 0x0023
|
||||||
#define ATT_CHARACTERISTIC_ORG_BLUETOOTH_CHARACTERISTIC_HID_INFORMATION_01_VALUE_HANDLE 0x0025
|
#define ATT_CHARACTERISTIC_ORG_BLUETOOTH_CHARACTERISTIC_HID_INFORMATION_01_VALUE_HANDLE 0x0025
|
||||||
#define ATT_CHARACTERISTIC_ORG_BLUETOOTH_CHARACTERISTIC_HID_CONTROL_POINT_01_VALUE_HANDLE 0x0027
|
#define ATT_CHARACTERISTIC_ORG_BLUETOOTH_CHARACTERISTIC_HID_CONTROL_POINT_01_VALUE_HANDLE 0x0027
|
||||||
|
#define ATT_CHARACTERISTIC_ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL_01_VALUE_HANDLE 0x002a
|
||||||
|
#define ATT_CHARACTERISTIC_ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL_01_CLIENT_CONFIGURATION_HANDLE 0x002b
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
#ifndef _BOARDS_WAVESHARE_RP2350B_PLUS_W_H
|
||||||
|
#define _BOARDS_WAVESHARE_RP2350B_PLUS_W_H
|
||||||
|
|
||||||
|
pico_board_cmake_set(PICO_PLATFORM, rp2350)
|
||||||
|
pico_board_cmake_set(PICO_CYW43_SUPPORTED, 1)
|
||||||
|
|
||||||
|
#define WAVESHARE_RP2350B_PLUS_W
|
||||||
|
|
||||||
|
// --- RP2350 VARIANT ---
|
||||||
|
#define PICO_RP2350A 0
|
||||||
|
|
||||||
|
// --- UART ---
|
||||||
|
#ifndef PICO_DEFAULT_UART
|
||||||
|
#define PICO_DEFAULT_UART 0
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_UART_TX_PIN
|
||||||
|
#define PICO_DEFAULT_UART_TX_PIN 0
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_UART_RX_PIN
|
||||||
|
#define PICO_DEFAULT_UART_RX_PIN 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --- LED ---
|
||||||
|
#ifndef PICO_DEFAULT_LED_PIN
|
||||||
|
#define PICO_DEFAULT_LED_PIN 23
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --- I2C ---
|
||||||
|
#ifndef PICO_DEFAULT_I2C
|
||||||
|
#define PICO_DEFAULT_I2C 1
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_I2C_SDA_PIN
|
||||||
|
#define PICO_DEFAULT_I2C_SDA_PIN 6
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_I2C_SCL_PIN
|
||||||
|
#define PICO_DEFAULT_I2C_SCL_PIN 7
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --- SPI ---
|
||||||
|
#ifndef PICO_DEFAULT_SPI
|
||||||
|
#define PICO_DEFAULT_SPI 0
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_SPI_SCK_PIN
|
||||||
|
#define PICO_DEFAULT_SPI_SCK_PIN 18
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_SPI_TX_PIN
|
||||||
|
#define PICO_DEFAULT_SPI_TX_PIN 19
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_SPI_RX_PIN
|
||||||
|
#define PICO_DEFAULT_SPI_RX_PIN 16
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_SPI_CSN_PIN
|
||||||
|
#define PICO_DEFAULT_SPI_CSN_PIN 17
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --- FLASH ---
|
||||||
|
#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
|
||||||
|
|
||||||
|
#ifndef PICO_FLASH_SPI_CLKDIV
|
||||||
|
#define PICO_FLASH_SPI_CLKDIV 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024))
|
||||||
|
#ifndef PICO_FLASH_SIZE_BYTES
|
||||||
|
#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --- CYW43 (RM2) on B-package extra pins ---
|
||||||
|
#ifndef CYW43_WL_GPIO_COUNT
|
||||||
|
#define CYW43_WL_GPIO_COUNT 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CYW43_WL_GPIO_LED_PIN
|
||||||
|
#define CYW43_WL_GPIO_LED_PIN 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CYW43_WL_GPIO_SMPS_PIN
|
||||||
|
#define CYW43_WL_GPIO_SMPS_PIN 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CYW43_WL_GPIO_VBUS_PIN
|
||||||
|
#define CYW43_WL_GPIO_VBUS_PIN 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CYW43_USES_VSYS_PIN
|
||||||
|
#define CYW43_USES_VSYS_PIN 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PICO_VSYS_PIN
|
||||||
|
#define PICO_VSYS_PIN 29
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CYW43_PIN_WL_DYNAMIC
|
||||||
|
#define CYW43_PIN_WL_DYNAMIC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CYW43_DEFAULT_PIN_WL_REG_ON
|
||||||
|
#define CYW43_DEFAULT_PIN_WL_REG_ON 36u
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CYW43_DEFAULT_PIN_WL_DATA_OUT
|
||||||
|
#define CYW43_DEFAULT_PIN_WL_DATA_OUT 37u
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CYW43_DEFAULT_PIN_WL_DATA_IN
|
||||||
|
#define CYW43_DEFAULT_PIN_WL_DATA_IN 37u
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CYW43_DEFAULT_PIN_WL_HOST_WAKE
|
||||||
|
#define CYW43_DEFAULT_PIN_WL_HOST_WAKE 37u
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CYW43_DEFAULT_PIN_WL_CLOCK
|
||||||
|
#define CYW43_DEFAULT_PIN_WL_CLOCK 39u
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CYW43_DEFAULT_PIN_WL_CS
|
||||||
|
#define CYW43_DEFAULT_PIN_WL_CS 38u
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1)
|
||||||
|
#ifndef PICO_RP2350_A2_SUPPORTED
|
||||||
|
#define PICO_RP2350_A2_SUPPORTED 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
10
cs_midi.h
10
cs_midi.h
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
// MIDI interfaces — common
|
// MIDI interfaces — common
|
||||||
#include <MIDI_Interfaces/MIDI_Pipes.hpp>
|
#include <MIDI_Interfaces/MIDI_Pipes.hpp>
|
||||||
|
#include <MIDI_Interfaces/MIDI_Callbacks.hpp>
|
||||||
|
|
||||||
// MIDI interfaces — transport-specific
|
// MIDI interfaces — transport-specific
|
||||||
#ifdef CS_MIDI_BLE
|
#ifdef CS_MIDI_BLE
|
||||||
|
|
@ -93,4 +94,13 @@ using BluetoothMIDI_Interface =
|
||||||
GenericBLEMIDI_Interface<BTstackBackgroundBackend>;
|
GenericBLEMIDI_Interface<BTstackBackgroundBackend>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CS_MIDI_HID_KEYBOARD) && defined(CS_MIDI_BLE)
|
||||||
|
namespace midi_ble_btstack {
|
||||||
|
void set_battery_level(uint8_t percent);
|
||||||
|
}
|
||||||
|
inline void setBLEBatteryLevel(uint8_t percent) {
|
||||||
|
midi_ble_btstack::set_battery_level(percent);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
END_CS_NAMESPACE
|
END_CS_NAMESPACE
|
||||||
|
|
|
||||||
2
docs
2
docs
|
|
@ -1 +1 @@
|
||||||
Subproject commit 3927d073e938973be113ee08db4e596c7d853ad3
|
Subproject commit be1ee309670a861adca5fb8f46aefe6a723a6bb4
|
||||||
|
|
@ -69,6 +69,9 @@ set(EXAMPLE_SOURCES
|
||||||
output/program_changer.cpp
|
output/program_changer.cpp
|
||||||
output/cc_potentiometers.cpp
|
output/cc_potentiometers.cpp
|
||||||
output/borrowed_cc_rotary_encoder.cpp
|
output/borrowed_cc_rotary_encoder.cpp
|
||||||
|
output/cc_potentiometer_map.cpp
|
||||||
|
output/finished_controller.cpp
|
||||||
|
output/enable_disable.cpp
|
||||||
|
|
||||||
# Input elements
|
# Input elements
|
||||||
input/note_led.cpp
|
input/note_led.cpp
|
||||||
|
|
@ -84,6 +87,11 @@ set(EXAMPLE_SOURCES
|
||||||
# Interfaces
|
# Interfaces
|
||||||
interfaces/ble_midi.cpp
|
interfaces/ble_midi.cpp
|
||||||
interfaces/midi_pipes.cpp
|
interfaces/midi_pipes.cpp
|
||||||
|
interfaces/midi_output.cpp
|
||||||
|
interfaces/send_midi_notes.cpp
|
||||||
|
interfaces/send_all_midi_messages.cpp
|
||||||
|
interfaces/midi_input_callback.cpp
|
||||||
|
interfaces/midi_pipes_filter.cpp
|
||||||
|
|
||||||
# Banks
|
# Banks
|
||||||
banks/bank_cc_values.cpp
|
banks/bank_cc_values.cpp
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
struct MyMIDI_Callbacks : MIDI_Callbacks {
|
||||||
|
void onChannelMessage(MIDI_Interface &, ChannelMessage msg) override {
|
||||||
|
(void)msg;
|
||||||
|
}
|
||||||
|
void onSysExMessage(MIDI_Interface &, SysExMessage msg) override {
|
||||||
|
(void)msg;
|
||||||
|
}
|
||||||
|
void onRealTimeMessage(MIDI_Interface &, RealTimeMessage msg) override {
|
||||||
|
(void)msg;
|
||||||
|
}
|
||||||
|
} callback;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
midi.begin();
|
||||||
|
midi.setCallbacks(callback);
|
||||||
|
while (true) {
|
||||||
|
midi.update();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
const MIDIAddress address {MIDI_Notes::C[4], Channel_1};
|
||||||
|
const uint8_t velocity = 0x7F;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
midi.begin();
|
||||||
|
while (true) {
|
||||||
|
midi.sendNoteOn(address, velocity);
|
||||||
|
sleep_ms(500);
|
||||||
|
midi.sendNoteOff(address, velocity);
|
||||||
|
sleep_ms(500);
|
||||||
|
midi.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
struct NoteFilter : MIDI_Pipe {
|
||||||
|
void mapForwardMIDI(ChannelMessage msg) override {
|
||||||
|
switch (msg.getMessageType()) {
|
||||||
|
case MIDIMessageType::NoteOff:
|
||||||
|
case MIDIMessageType::NoteOn:
|
||||||
|
msg.setChannel(Channel_5);
|
||||||
|
if (msg.data1 >= 12)
|
||||||
|
msg.data1 -= 12;
|
||||||
|
sourceMIDItoSink(msg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void mapForwardMIDI(SysExMessage) override {}
|
||||||
|
void mapForwardMIDI(SysCommonMessage) override {}
|
||||||
|
void mapForwardMIDI(RealTimeMessage msg) override {
|
||||||
|
sourceMIDItoSink(msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NoteFilter filter;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
midi >> filter >> midi;
|
||||||
|
midi.begin();
|
||||||
|
while (true) {
|
||||||
|
midi.update();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
midi.begin();
|
||||||
|
|
||||||
|
// Channel voice messages
|
||||||
|
MIDIAddress note = {MIDI_Notes::C[4], Channel_6};
|
||||||
|
midi.sendNoteOn(note, 127);
|
||||||
|
midi.sendNoteOff(note, 127);
|
||||||
|
midi.sendKeyPressure(note, 64);
|
||||||
|
|
||||||
|
MIDIAddress controller = {MIDI_CC::Channel_Volume, Channel_2};
|
||||||
|
midi.sendControlChange(controller, 120);
|
||||||
|
|
||||||
|
MIDIAddress program = {MIDI_PC::Harpsichord, Channel_9};
|
||||||
|
midi.sendProgramChange(program);
|
||||||
|
|
||||||
|
midi.sendChannelPressure(Channel_3, 64);
|
||||||
|
midi.sendPitchBend(Channel_3, 16383);
|
||||||
|
|
||||||
|
// System common messages
|
||||||
|
midi.sendMTCQuarterFrame(2, 15);
|
||||||
|
midi.sendSongPositionPointer(10000);
|
||||||
|
midi.sendSongSelect(70);
|
||||||
|
midi.sendTuneRequest();
|
||||||
|
|
||||||
|
// System exclusive
|
||||||
|
uint8_t sysex[] = {0xF0, 0x00, 0x01, 0x02, 0x03, 0xF7};
|
||||||
|
midi.sendSysEx(sysex);
|
||||||
|
|
||||||
|
// Real-time messages
|
||||||
|
midi.sendTimingClock();
|
||||||
|
midi.sendStart();
|
||||||
|
midi.sendContinue();
|
||||||
|
midi.sendStop();
|
||||||
|
midi.sendActiveSensing();
|
||||||
|
midi.sendSystemReset();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
midi.update();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
AH::Button pushbutton {5};
|
||||||
|
|
||||||
|
const MIDIAddress noteAddress {MIDI_Notes::C[4], Channel_1};
|
||||||
|
const uint8_t velocity = 0x7F;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
pushbutton.begin();
|
||||||
|
midi.begin();
|
||||||
|
while (true) {
|
||||||
|
midi.update();
|
||||||
|
pushbutton.update();
|
||||||
|
if (pushbutton.getState() == AH::Button::Falling)
|
||||||
|
midi.sendNoteOn(noteAddress, velocity);
|
||||||
|
else if (pushbutton.getState() == AH::Button::Rising)
|
||||||
|
midi.sendNoteOff(noteAddress, velocity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
CCPotentiometer potentiometer {26, {MIDI_CC::Channel_Volume, Channel_1}};
|
||||||
|
|
||||||
|
constexpr analog_t maxRawValue = CCPotentiometer::getMaxRawValue();
|
||||||
|
constexpr analog_t minimumValue = maxRawValue / 64;
|
||||||
|
constexpr analog_t maximumValue = maxRawValue - maxRawValue / 64;
|
||||||
|
|
||||||
|
analog_t mappingFunction(analog_t raw) {
|
||||||
|
if (raw < minimumValue) raw = minimumValue;
|
||||||
|
if (raw > maximumValue) raw = maximumValue;
|
||||||
|
return (raw - minimumValue) * maxRawValue / (maximumValue - minimumValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
potentiometer.map(mappingFunction);
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
NoteButton button1 {5, {MIDI_Notes::C[4], Channel_1}};
|
||||||
|
NoteButton button2 {6, {MIDI_Notes::D[4], Channel_1}};
|
||||||
|
AH::Button toggleBtn {7};
|
||||||
|
|
||||||
|
bool button2Enabled = true;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
toggleBtn.begin();
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
toggleBtn.update();
|
||||||
|
if (toggleBtn.getState() == AH::Button::Falling) {
|
||||||
|
button2Enabled = !button2Enabled;
|
||||||
|
if (button2Enabled)
|
||||||
|
button2.enable();
|
||||||
|
else
|
||||||
|
button2.disable();
|
||||||
|
}
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#include <cs_midi.h>
|
||||||
|
|
||||||
|
using namespace cs;
|
||||||
|
|
||||||
|
BluetoothMIDI_Interface midi;
|
||||||
|
|
||||||
|
// 4 banks, 2 tracks per bank
|
||||||
|
Bank<4> bank(2);
|
||||||
|
|
||||||
|
// Two buttons to cycle banks
|
||||||
|
IncrementDecrementSelector<4> bankSelector {bank, {2, 3}, Wrap::Wrap};
|
||||||
|
|
||||||
|
// Bankable CC value readers — bank switches the CC address
|
||||||
|
Bankable::CCValue<4> volume1 {{bank, BankType::ChangeAddress}, {16, Channel_1}};
|
||||||
|
Bankable::CCValue<4> volume2 {{bank, BankType::ChangeAddress}, {17, Channel_1}};
|
||||||
|
|
||||||
|
// Non-bankable output elements
|
||||||
|
NoteButton button {5, {MIDI_Notes::C[4], Channel_1}};
|
||||||
|
CCPotentiometer pot {26, {MIDI_CC::Channel_Volume, Channel_1}};
|
||||||
|
CCRotaryEncoder enc {{0, 1}, {MIDI_CC::Pan, Channel_1}, 1, 4};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
if (cyw43_arch_init()) return 1;
|
||||||
|
Control_Surface.begin();
|
||||||
|
while (true) {
|
||||||
|
Control_Surface.loop();
|
||||||
|
sleep_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue