-
Notifications
You must be signed in to change notification settings - Fork 423
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add BluetoothHIDMaster documentation (#2216)
Also link in FatFSUSB docs, d'oh!
- Loading branch information
1 parent
1fd66bf
commit f8c1ec1
Showing
4 changed files
with
218 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,208 @@ | ||
Bluetooth HID Master | ||
==================== | ||
|
||
The PicoW can connect to a Bluetooth Classic or Bluetooth BLE keyboard, | ||
mouse, or joystick and receive input events from it. As opposed to | ||
the ``Keyboard``, ``Mouse``, and ``Joystick`` libraries, which make | ||
the PicoW into a peripheral others can use, this lets the PicoW use the | ||
same kinds of peripherals in a master rols. | ||
|
||
BTDeviceInfo Class | ||
------------------ | ||
|
||
The ``BluetoothHCI`` class implements a scanning function for classic | ||
and BLE devices and can return a ``std::list`` of discovered devices to an application. | ||
Iterate over the list using any of the STL iteration methods (i.e. ``for (auto e : list)``). | ||
The elements of this list are ``BTDeviceInfo`` objects which have the following | ||
member functions: | ||
|
||
``BTDeviceInfo::deviceClass()`` returns the Bluetooth BLE UUID or the Blustooth device | ||
class for the device. This specifies the general class of the device (keyboard, mouse, | ||
etc.). | ||
|
||
``BTDeviceInfo::address()`` and ``BTDeviceInfo::addressString()`` return the | ||
Bluetooth address as a binary array or a string that can be used to ``print``. | ||
|
||
``BTDeviceInfo::addressType()`` returns whether the BLE address is random or not, and | ||
is not generally needed by a user application. | ||
|
||
``BTDeviceInfo::rssi()`` returns an approximate dB level for the device. Less | ||
negative is stronger signal. | ||
|
||
``BTDeviceInfo::name()`` returns the advertised name of the device, if present. Some | ||
devices or scans do not return names for valid devices. | ||
|
||
|
||
BluetoothHCI Class | ||
------------------ | ||
|
||
The ``BluetoothHCI`` class is responsible for scanning for devices and the lower-level | ||
housekeeping for a master-mode Bluetooth application. Most applications will not need | ||
to access it directly, but it can be used to discover nearby BT devices. As | ||
part of the application Bluetooth setup, call ``BluetoothHCI::install()`` and then | ||
``BluetoothHCI::begin()`` to start BT processing. Your application is still responsible | ||
for all the non-default HCI initialization and customization. See the ``BluetoothScanner.ino`` | ||
example for more info. | ||
|
||
|
||
BluetoothHIDMaster Operation | ||
---------------------------- | ||
|
||
Most applications will use the ``BluetoothHIDMaster`` class and, after connecting, receive | ||
callbacks from the Bluetooth stack when input events (key presses, mouse moves, button | ||
mashes) occur. | ||
|
||
Application flow will generally be: | ||
1. Install the appropriate callbacks using the ``BluetoothHIDMaster::onXXX`` methods | ||
2. Start the Bluetooth processing with ``BluetoothHIDMaster::begin()`` or ``BluetoothHIDMaster::beginBLE()`` | ||
3. Connect to the first device found with ``BluetoothHIDMaster::connectXXX()`` and start receiving callbacks. | ||
4. Callbacks will come at interrupt time and set global state variables, which the main ``loop()`` will process | ||
|
||
Callback Event Handlers | ||
----------------------- | ||
The main application is informed of new inputs via a standard callback mechanism. These callbacks run at | ||
interrupt time and should not do significant work, ``delay()``, or allocate or free memory. The most common | ||
way of handling this is setting global ``volatile`` flags and variables that the main ``loop()`` will poll | ||
and process. | ||
|
||
Mouse Callbacks | ||
~~~~~~~~~~~~~~~ | ||
The ``BluetoothHIDMaster::onMouseMove`` callback gets the delta X, Y, and wheel reported by the device. | ||
The ``BluetoothHIDMaster::onMouseButton`` gets a button number and state (up or down) and will be called | ||
each time an individual button is reported changed by the mouse. | ||
|
||
.. code :: cpp | ||
void mouseMoveCB(void *cbdata, int dx, int dy, int dw) { | ||
// Process the deltas, adjust global mouse state | ||
} | ||
void mouseButtonCB(void *cbdata, int butt, bool down) { | ||
// Set the global button array with this new info | ||
} | ||
Meyboard Callbacks | ||
~~~~~~~~~~~~~~~~~~ | ||
The `BluetoothHIDMaster::onKeyDown`` callback receives the raw HID key (**NOT ASCII**) sent by the device on a key press | ||
while `BluetoothHIDMaster::onKeyUp`` gets the same when a key is released. Note that up to 6 keys can be pressed at any | ||
one time. For media keys ("consumer keys" in the USB HID documentation) the ``BluetoothHIDMaster::onConsumerKeyDown`` and | ||
``BluetoothHIDMaster::onConsumerKeyUp`` perform the same function (and receive the consumer key IDs defined by the | ||
USB HID spec and not ASCII). | ||
|
||
To convert the key press and release (including SHIFT handling), use a ``HIDKeyStream`` object. Simply write the raw | ||
HID key and the up/down state to the stream and read back the ASCII for use in an application. | ||
|
||
.. code :: cpp | ||
HIDKeyStream keystream; | ||
void keyDownCB(void *cbdata, int key) { | ||
keystream.write((uint8_t )key); | ||
keystream.write((uint8_t) true); // Keystream now has 1 ASCII character to read out and use | ||
char ascii = keystream.read(); | ||
// .... | ||
} | ||
void keyUpCB(void *cbdata, int key) { | ||
// Normally don't do anything on this, the character was read in the keyDownCB | ||
} | ||
void consumerKeyDownCB(void *cbdata, int key) { | ||
// switch(key) and use cases from the USB Consumer Key page | ||
} | ||
void consumerKeyUpCB(void *cbdata, int key) { | ||
// switch(key) and use cases from the USB Consumer Key page | ||
} | ||
Joystick Callbacks | ||
~~~~~~~~~~~~~~~~~~ | ||
A single ``BluetoothHIDMaster::onJoypad`` callback gets activated every time a report from a joystick is processed. | ||
It receives (potentially, if supported by the device) 4 analog axes, one 8-way digital hat switch position, and up | ||
to 32 button states at a time. | ||
|
||
.. code :: cpp | ||
void joypadCB(void *cbdata, int x, int y, int z, int rz, uint8_t hat, uint32_t buttons) { | ||
// HAT 0 = UP and continues clockwise. If no hat direction it is set to 0x0f. | ||
// Use "buttons & (1 << buttonNumber)" to look at the individual button states | ||
// ... | ||
} | ||
PianoKeyboard Example | ||
~~~~~~~~~~~~~~~~~~~~~ | ||
See the ``PianoKeyboard.ino`` and ``PianoKeyboardBLE.ino`` examples for more information on callback operation. | ||
|
||
|
||
BluetoothHIDMaster::onXXX Callback Installers | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
.. code :: cpp | ||
void BluetoothHIDMaster::onMouseMove(void (*)(void *, int, int, int), void *cbData = nullptr); | ||
void BluetoothHIDMaster::onMouseButton(void (*)(void *, int, bool), void *cbData = nullptr); | ||
void BluetoothHIDMaster::onKeyDown(void (*)(void *, int), void *cbData = nullptr); | ||
void BluetoothHIDMaster::onKeyUp(void (*)(void *, int), void *cbData = nullptr); | ||
void BluetoothHIDMaster::onConsumerKeyDown(void (*)(void *, int), void *cbData = nullptr); | ||
void BluetoothHIDMaster::onConsumerKeyUp(void (*)(void *, int), void *cbData = nullptr); | ||
void BluetoothHIDMaster::onJoypad(void (*)(void *, int, int, int, int, uint8_t, uint32_t), void *cbData = nullptr); | ||
BluetoothHIDMaster Class | ||
------------------------ | ||
|
||
bool BluetoothHIDMaster::begin() | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
Installs and configures the Bluetooth Classic stack and starts processing events. No connections are made at this point. | ||
When running in Classic mode, no BLE devices can be detected or used. | ||
|
||
|
||
bool BluetoothHIDMaster::begin(const char *BLEName) | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
Installs and configures the Bluetooth BLE stack and starts processing events. No connections are made at this point. | ||
When running in BLE mode, no Classic devices can be detected or used. | ||
bool BluetoothHIDMaster::connected() | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
Returns if the Bluetooth stack is up and running and a connection to a device is currently active. | ||
|
||
void BluetoothHIDMaster::end() | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
Disables the Bluetooth stack. Note that with the current Bluetooth implementation restarting the stack (i.e. calling ``begin()`` after ``end()``) is not stable and will not work. Consider storing state and rebooting completely if this is necessary. | ||
|
||
bool BluetoothHIDMaster::running() | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
Returns if the Bluetooth stack is running at all. Does not indicate if there is an active connection or not. | ||
|
||
bool BluetoothHIDMaster::hciRunning() | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
Returns if the Bluetooth stack has passed the initial HCI start up phase. Until this returns ``true`` no Bluetooth operations can be performed. | ||
|
||
std::list<BTDeviceInfo> BluetoothHIDMaster::scan(uint32_t mask, int scanTimeSec, bool async) | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
Passes through the ``BluetoothHCI::scan()`` function to manually scan for a list of nearby devices. If you want to connect to the first found device, this is not needed. | ||
|
||
bool BluetoothHIDMaster::connect(const uint8_t *addr) | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
Start the connection process to the Bluetooth Classic device with the given MAC. Note that this returns immediately, but it may take several seconds until ``connected()`` reports that the connection has been established. | ||
bool BluetoothHIDMaster::connectKeyboard(), connectMouse(), connectJoypad(), connectAny() | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
Connect to the first found specified Bluetooth Classic device type (or any HID device) in pairing mode. No need to call ``scan()`` or have an address. | ||
|
||
bool BluetoothHIDMaster::connectBLE(const uint8_t *addr, int addrType) | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
Start the connection process to the Bluetooth BLE device with the given MAC. Note that this returns immediately, but it may take several seconds until ``connected()`` reports that the connection has been established. | ||
bool BluetoothHIDMaster::connectBLE() | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
Connect to the first found BLE device that has a HID service UUID (keyboard, mouse, or joystick) | ||
|
||
bool BluetoothHIDMaster::disconnect() | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
Shuts down the connection to the currently connected device. | ||
|
||
void BluetoothHIDMaster::clearPairing() | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
Erases all Bluetooth keys from memory. This effectively "forgets" all pairing between devices and can help avoid issues with the beta Bluetooth stack in the SDK. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters