mirror of
https://github.com/morgan9e/scripts
synced 2026-04-14 00:14:13 +09:00
153 lines
5.1 KiB
C++
153 lines
5.1 KiB
C++
#include "BLEDevice.h"
|
|
#include "BLEHIDDevice.h"
|
|
#include "HIDTypes.h"
|
|
|
|
#define DEVICE_NAME "ESP32 Mouse"
|
|
#define BLE_MANUFACTURER "TinyUSB"
|
|
|
|
BLEHIDDevice* hid;
|
|
BLECharacteristic* input;
|
|
BLECharacteristic* output;
|
|
bool isBleConnected = false;
|
|
|
|
#define MOUSE_LEFT 1
|
|
#define MOUSE_RIGHT 2
|
|
#define MOUSE_MIDDLE 4
|
|
|
|
struct InputReport {
|
|
uint8_t buttons;
|
|
int8_t x;
|
|
int8_t y;
|
|
int8_t w;
|
|
int8_t hw;
|
|
};
|
|
|
|
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
Serial2.begin(115200, SERIAL_8N1, 22, 23);
|
|
xTaskCreate(bluetoothTask, "bluetooth", 20000, NULL, 5, NULL);
|
|
}
|
|
|
|
void loop() {
|
|
while (Serial2.available()) {
|
|
String uartData = Serial2.readStringUntil('\n');
|
|
if (uartData.startsWith("REPORT: ")) {
|
|
int r, m, l, w, x, y;
|
|
sscanf(uartData.c_str(), "REPORT: BTN %d %d %d WHEEL %d X %d Y %d", &l, &m, &r, &w, &x, &y);
|
|
|
|
uint8_t button = 0;
|
|
|
|
if (r) button |= MOUSE_RIGHT;
|
|
else button &= ~MOUSE_RIGHT;
|
|
|
|
if (m) button |= MOUSE_MIDDLE;
|
|
else button &= ~MOUSE_MIDDLE;
|
|
|
|
if (l) button |= MOUSE_LEFT;
|
|
else button &= ~MOUSE_LEFT;
|
|
|
|
InputReport report = {
|
|
.buttons = button,
|
|
.x = x,
|
|
.y = y,
|
|
.w = w,
|
|
.hw = 0
|
|
};
|
|
|
|
if (isBleConnected) {
|
|
input->setValue((uint8_t*)&report, sizeof(report));
|
|
input->notify();
|
|
}
|
|
}
|
|
// Serial.println(uartData);
|
|
}
|
|
}
|
|
|
|
static const uint8_t _hidReportDescriptor[] = {
|
|
USAGE_PAGE(1), 0x01, // USAGE_PAGE (Generic Desktop)
|
|
USAGE(1), 0x02, // USAGE (Mouse)
|
|
COLLECTION(1), 0x01, // COLLECTION (Application)
|
|
USAGE(1), 0x01, // USAGE (Pointer)
|
|
COLLECTION(1), 0x00, // COLLECTION (Physical)
|
|
// ------------------------------------------------- Buttons (Left, Right, Middle, Back, Forward)
|
|
USAGE_PAGE(1), 0x09, // USAGE_PAGE (Button)
|
|
USAGE_MINIMUM(1), 0x01, // USAGE_MINIMUM (Button 1)
|
|
USAGE_MAXIMUM(1), 0x05, // USAGE_MAXIMUM (Button 5)
|
|
LOGICAL_MINIMUM(1), 0x00, // LOGICAL_MINIMUM (0)
|
|
LOGICAL_MAXIMUM(1), 0x01, // LOGICAL_MAXIMUM (1)
|
|
REPORT_SIZE(1), 0x01, // REPORT_SIZE (1)
|
|
REPORT_COUNT(1), 0x05, // REPORT_COUNT (5)
|
|
HIDINPUT(1), 0x02, // INPUT (Data, Variable, Absolute) ;5 button bits
|
|
// ------------------------------------------------- Padding
|
|
REPORT_SIZE(1), 0x03, // REPORT_SIZE (3)
|
|
REPORT_COUNT(1), 0x01, // REPORT_COUNT (1)
|
|
HIDINPUT(1), 0x03, // INPUT (Constant, Variable, Absolute) ;3 bit padding
|
|
// ------------------------------------------------- X/Y position, Wheel
|
|
USAGE_PAGE(1), 0x01, // USAGE_PAGE (Generic Desktop)
|
|
USAGE(1), 0x30, // USAGE (X)
|
|
USAGE(1), 0x31, // USAGE (Y)
|
|
USAGE(1), 0x38, // USAGE (Wheel)
|
|
LOGICAL_MINIMUM(1), 0x81, // LOGICAL_MINIMUM (-127)
|
|
LOGICAL_MAXIMUM(1), 0x7f, // LOGICAL_MAXIMUM (127)
|
|
REPORT_SIZE(1), 0x08, // REPORT_SIZE (8)
|
|
REPORT_COUNT(1), 0x03, // REPORT_COUNT (3)
|
|
HIDINPUT(1), 0x06, // INPUT (Data, Variable, Relative) ;3 bytes (X,Y,Wheel)
|
|
// ------------------------------------------------- Horizontal wheel
|
|
USAGE_PAGE(1), 0x0c, // USAGE PAGE (Consumer Devices)
|
|
USAGE(2), 0x38, 0x02, // USAGE (AC Pan)
|
|
LOGICAL_MINIMUM(1), 0x81, // LOGICAL_MINIMUM (-127)
|
|
LOGICAL_MAXIMUM(1), 0x7f, // LOGICAL_MAXIMUM (127)
|
|
REPORT_SIZE(1), 0x08, // REPORT_SIZE (8)
|
|
REPORT_COUNT(1), 0x01, // REPORT_COUNT (1)
|
|
HIDINPUT(1), 0x06, // INPUT (Data, Var, Rel)
|
|
END_COLLECTION(0), // END_COLLECTION
|
|
END_COLLECTION(0) // END_COLLECTION
|
|
};
|
|
|
|
class BleHIDCallbacks : public BLEServerCallbacks {
|
|
void onConnect(BLEServer* server) {
|
|
isBleConnected = true;
|
|
BLE2902* cccDesc = (BLE2902*)input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
|
|
cccDesc->setNotifications(true);
|
|
Serial.println("CONNECTED");
|
|
}
|
|
|
|
void onDisconnect(BLEServer* server) {
|
|
isBleConnected = false;
|
|
BLE2902* cccDesc = (BLE2902*)input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
|
|
cccDesc->setNotifications(false);
|
|
Serial.println("DISCONNECTED");
|
|
}
|
|
};
|
|
|
|
void bluetoothTask(void*) {
|
|
BLEDevice::init(DEVICE_NAME);
|
|
BLEServer* server = BLEDevice::createServer();
|
|
server->setCallbacks(new BleHIDCallbacks());
|
|
|
|
hid = new BLEHIDDevice(server);
|
|
input = hid->inputReport(0);
|
|
|
|
hid->manufacturer()->setValue(BLE_MANUFACTURER);
|
|
hid->pnp(0x02, 0xe502, 0xa111, 0x0210);
|
|
hid->hidInfo(0x00, 0x02);
|
|
|
|
BLESecurity* security = new BLESecurity();
|
|
security->setAuthenticationMode(ESP_LE_AUTH_BOND);
|
|
|
|
hid->reportMap((uint8_t*)_hidReportDescriptor, sizeof(_hidReportDescriptor));
|
|
hid->startServices();
|
|
hid->setBatteryLevel(100);
|
|
|
|
BLEAdvertising* advertising = server->getAdvertising();
|
|
advertising->setAppearance(HID_MOUSE);
|
|
advertising->addServiceUUID(hid->hidService()->getUUID());
|
|
advertising->addServiceUUID(hid->deviceInfo()->getUUID());
|
|
advertising->addServiceUUID(hid->batteryService()->getUUID());
|
|
advertising->start();
|
|
|
|
Serial.println("BLE READY");
|
|
delay(portMAX_DELAY);
|
|
};
|