Skip to content

Commit 82c63d9

Browse files
committed
Add HCI support
1 parent 20f21e7 commit 82c63d9

File tree

2 files changed

+119
-2
lines changed

2 files changed

+119
-2
lines changed

adafruit_ble/__init__.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,12 @@ class BLERadio:
156156
It uses this library's `Advertisement` classes and the `BLEConnection` class."""
157157

158158
def __init__(self, adapter=None):
159-
if not adapter:
160-
adapter = _bleio.adapter
159+
if not _bleio.adapter:
160+
# Try setting up an onboard HCI BLE adapter.
161+
from adafruit_ble import hci # pylint: disable=import-outside-toplevel
162+
163+
adapter = hci.create_adapter()
164+
_bleio.set_adapter(adapter)
161165
self._adapter = adapter
162166
self._current_advertisement = None
163167
self._connection_cache = {}

adafruit_ble/hci.py

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# The MIT License (MIT)
2+
#
3+
# Copyright (c) 2020 Dan Halbert for Adafruit Industries
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
13+
# all 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
21+
# THE SOFTWARE.
22+
"""
23+
Sets up an on-board HCI BLE adapter.
24+
"""
25+
26+
import time
27+
28+
import board
29+
import busio
30+
import digitalio
31+
import _bleio
32+
33+
34+
def create_adapter_esp32_hci(
35+
*,
36+
esp_reset=board.ESP_RESET,
37+
esp_gpio0=board.ESP_GPIO0,
38+
esp_busy=board.ESP_BUSY,
39+
esp_cs=board.ESP_CS,
40+
esp_tx=board.ESP_TX,
41+
esp_rx=board.ESP_RX,
42+
reset_high=False,
43+
debug=False
44+
):
45+
"""Do ESP32-specific HCI adapter initialization."""
46+
47+
reset = digitalio.DigitalInOut(esp_reset)
48+
reset.switch_to_output(not reset_high)
49+
50+
gpio0_and_rts = digitalio.DigitalInOut(esp_gpio0)
51+
cts = digitalio.DigitalInOut(esp_busy)
52+
chip_select = digitalio.DigitalInOut(esp_cs)
53+
54+
uart = busio.UART(
55+
esp_tx, esp_rx, baudrate=115200, timeout=0, receiver_buffer_size=512
56+
)
57+
58+
# Boot ESP32 from SPI flash.
59+
gpio0_and_rts.switch_to_output(True)
60+
61+
# Choose Bluetooth mode.
62+
chip_select.switch_to_output(False)
63+
64+
# Start reset
65+
reset.value = reset_high
66+
time.sleep(0.1)
67+
68+
# Release reset and wait for startup and startup message.
69+
reset.value = not reset_high
70+
time.sleep(1.0)
71+
72+
startup_message = b""
73+
while uart.in_waiting: # pylint: disable=no-member
74+
more = uart.read()
75+
if more:
76+
startup_message += more
77+
78+
if not startup_message:
79+
raise _bleio.BluetoothError(
80+
"HCI adapter did not respond with a startup message"
81+
)
82+
83+
if debug:
84+
try:
85+
print(startup_message.decode("utf-8"))
86+
except UnicodeError:
87+
raise _bleio.BluetoothError("Garbled HCI startup message")
88+
89+
# pylint: disable=no-member
90+
return _bleio.Adapter(uart=uart, rts=gpio0_and_rts, cts=cts)
91+
92+
93+
def create_adapter(debug=False):
94+
"""Determine whether an on-board HCI adapter is available, and initialize it.
95+
Currently only ESP32 co-processors are supported.
96+
"""
97+
# See if all the pins we need for an ESP32 HCI adapter are available.
98+
if all(
99+
pin in dir(board)
100+
for pin in ("ESP_RESET", "ESP_GPIO0", "ESP_BUSY", "ESP_CS", "ESP_TX", "ESP_RX")
101+
):
102+
return create_adapter_esp32_hci(
103+
esp_reset=board.ESP_RESET,
104+
esp_gpio0=board.ESP_GPIO0,
105+
esp_busy=board.ESP_BUSY,
106+
esp_cs=board.ESP_CS,
107+
esp_tx=board.ESP_TX,
108+
esp_rx=board.ESP_RX,
109+
reset_high=False,
110+
debug=debug,
111+
)
112+
else:
113+
raise _bleio.BluetoothError("ESP32 HCI adapter pins not available")

0 commit comments

Comments
 (0)