verypossible-labs / harald

An Elixir Bluetooth HCI data binding.
https://hexdocs.pm/harald
MIT License
83 stars 11 forks source link

Create documentation from Slack convos regarding Bluetooth on Nerves systems #30

Closed danielspofford closed 5 years ago

danielspofford commented 5 years ago

Placeholder issue to dump info from Slack until I can deal with it more officially.

danielspofford commented 5 years ago
fhunleth   [Yesterday at 11:13 AM]
Oh, you said BBBW. That might be different.
51 replies

Daniel Spofford   [23 hours ago]
I have that schematic for the BBBW though, let me check. I _really_ appreciate this information though. Knowing what to look for and where is 95% of this battle.

Daniel Spofford   [22 hours ago]
Doesn’t seem to have the same info like the BBGW you linked

https://github.com/beagleboard/beaglebone-black-wireless/blob/master/BeagleBone_Black_Wireless_SCH.pdf

The BBBW SRM wiki page is not particularly helpful here either: https://github.com/beagleboard/beaglebone-black-wireless/wiki/System-Reference-Manual-(WIP)

fhunleth   [21 hours ago]
Just getting back to slack. Did you figure it out?

Daniel Spofford   [20 hours ago]
No

Daniel Spofford   [20 hours ago]
These are my only additions to current fwup conf from standard BBB system:
        ```uboot_setenv(uboot-env, "enable_uboot_overlays", "1")
        uboot_setenv(uboot-env, "uboot_overlay_addr4", "BB-SPIDEV0-00A0.dtbo")
        uboot_setenv(uboot-env, "uboot_overlay_addr5", "BB-BBBW-WL1835-00A0.dtbo")
        uboot_setenv(uboot-env, "cape_enable=capemgr.enable_partno", "BB-UART3")```

Daniel Spofford   [20 hours ago]
I know there is a a bunch of bluez stuff to play with in buildroot, but I don’t know enough about linux+bluez to know if I even need bluez for what I am trying to do. I would hope I don’t.

Daniel Spofford   [20 hours ago]
I do have wifi connectivity though, if that makes a difference.

fhunleth   [20 hours ago]
You shouldn't have to do anything with Bluez since you're going direct to the UART.

fhunleth   [20 hours ago]
Here's the key part of the schematic:

fhunleth   [20 hours ago]
Pasted image at 2019-04-11, 3:03 PM 

fhunleth   [20 hours ago]
Pasted image at 2019-04-11, 3:04 PM 

fhunleth   [20 hours ago]
The BT_HCI_* pins. They connect to MII1_RXD2, MII_RXD3, MDIO_CLK, and MDIO_DATA. Let me see what those are...

fhunleth   [20 hours ago]
Looks like UART3

Daniel Spofford   [20 hours ago]
Yeah I have been trying UART3 for a bit now, I saw it mentioned in `BB-BBBW-WL1835-00A0.dtbo`, but I seem to be “talking to myself” when sending commands (edited)

Daniel Spofford   [20 hours ago]
By trying that I mean point harald at `/dev/ttyS3` (edited)

fhunleth   [20 hours ago]
The BT_EN (Bluetooth enable) connection looks different between the BBGW and BBBW. The BBGW has it at GPIO1_28 (aka GPIO 60) and the BBBW has it at GPIO0_28 (aka GPIO 28).

fhunleth   [20 hours ago]
That's kind of annoying, but I'd check that Bluetooth actually is enabled.

fhunleth   [20 hours ago]
The WL1835 hardware integration guide says this:

fhunleth   [20 hours ago]
Pasted image at 2019-04-11, 3:24 PM 

fhunleth   [20 hours ago]
http://www.ti.com/lit/ug/swru437a/swru437a.pdf

fhunleth   [20 hours ago]
Is the UART configured with hardware flow control to make sure the CTS line is set properly?

Daniel Spofford   [19 hours ago]
How would I go about checking Bluetooth is actually enabled?
--
I am not specifying `:flow_control` at all when opening with circ.uart, so I assume it is defaulting to `:none`, I will specify `:hardware` and report back.

Daniel Spofford   [19 hours ago]
FYI: I was _only_ specifying `speed: 115_200` previously.

Daniel Spofford   [19 hours ago]
Flow control hardware didn’t make it work.

Daniel Spofford   [19 hours ago]
The wifi LED on my board is lit but the BT LED isn’t. That seems telling.

fhunleth   [19 hours ago]
Yeah, It looks like the BT enable is connected to the LED too. Getting the LED to light sounds like a really good thing to do.

Daniel Spofford   [17 hours ago]
Setting  GPIO 28 hi via Circuits.GPIO causes BT LED to come on and now when I a attempt a scan I can verify I am getting back a command complete event :tada:. *But*, now I am experiencing similar functionality to what you were earlier today - it isn’t seeing any devices. Gonna clean up some of the changes I made then switch back to RPI3 and compare what a scan over there returns.

Daniel Spofford   [16 hours ago]
Every time I initiate a BT scan it tips something over:

```# SNIP
iex(33)> Bluetooth.LE.scan(:bt, time: 30000)

22:36:30.866 [warn]  atlantis: <<4, 14, 4, 1, 12, 32, 0>>

22:36:33.382 [info]  [ 3846.255721] wlcore: Beacon loss detected. roles:0x1

22:36:33.384 [info]  WiFiManager(wlan0): ignoring event: :"CTRL-EVENT-BEACON-LOSS"

22:36:33.388 [info]  Nerves.WpaSupplicant - WiFiManager(wlan0, up) got event :noop

22:36:38.284 [info]  nerves_network_interface received :ifchanged and %{ifname: "wlan0", index: 3, is_broadcast: true, is_lower_up: false, is_multicast: true, is_running: false, is_up: true, mac_address: "18:62:e4:06:e3:d2", mac_broadcast: "ff:ff:ff:ff:ff:ff", mtu: 1500, operstate: :down, stats: %{collisions: 0, multicast: 0, rx_bytes: 1346042, rx_dropped: 0, rx_errors: 0, rx_packets: 4780, tx_bytes: 81235, tx_dropped: 0, tx_errors: 0, tx_packets: 567}, type: :ethernet}

22:36:38.285 [info]  WiFiManager(wlan0) network_interface ifup

22:36:38.294 [info]  [ 3851.152635] wlcore: Connection loss work (role_id: 0).

22:36:38.294 [info]  [ 3851.152698] wlan0: Connection to AP 14:59:c0:38:3e:13 lost

22:36:38.316 [info]  Nerves.NetworkInterface - WiFiManager(wlan0, up) got event :ifup

22:36:38.797 [warn]  [ 3851.668562] wlcore: WARNING Unable to flush all TX buffers, timed out (timeout 500 ms

22:36:39.326 [warn]  [ 3852.198085] wlcore: WARNING Unable to flush all TX buffers, timed out (timeout 500 ms

22:36:39.833 [info]  WiFiManager(wlan0) wpa_supplicant wifi_disconnected

22:36:39.837 [info]  Nerves.WpaSupplicant - WiFiManager(wlan0, up) got event :wifi_disconnected

22:36:39.844 [warn]  [ 3852.700652] wlcore: WARNING Unable to flush all TX buffers, timed out (timeout 500 ms

22:36:39.845 [info]  Nerves.WpaSupplicant: sending 'REASSOCIATE'

22:36:39.931 [info]  WiFiManager(wlan0): ignoring event: {:"CTRL-EVENT-BSS-REMOVED", 17, "14:59:c0:38:3e:13"}
# SNIP```

fhunleth   [16 hours ago]
Whoa. That's special.

fhunleth   [16 hours ago]
Does the scan time get sent to the BT module?

Daniel Spofford   [16 hours ago]
No the timing stays within elixir, tell BT to start scan, Process.send_after, tell BT to stop scan.

fhunleth   [16 hours ago]
Ok, got it.

fhunleth   [16 hours ago]
Here's what I think is happening.

fhunleth   [16 hours ago]
Both BT and WiFi have to share 2.4 GHz. TI has some logic in the model that keeps them from stomping on each other. When you start a scan, that's like holding a mutex on the radio. When you stop the scan, that's like releasing the mutex. While BT is holding the radio, that's preventing WiFi from doing it's standard house keeping. Based on the timeouts, it seems like there's an important WiFi task that times out at 3 seconds.

fhunleth   [16 hours ago]
I think there is some convention to BT scanning where you do it for a second or less, then wait, then repeat.

fhunleth   [16 hours ago]
I don't know enough about this part to say, but I have run into BT/WiFi coexistence issues in projects before to know it's a thing.

Daniel Spofford   [15 hours ago]
Yeah duty cycle scanning.

Daniel Spofford   [15 hours ago]
You can configure a scan with scan_interval and scan_window. Window is how long to scan, interval is how long since you started the last scan before you start the next scan.

Daniel Spofford   [15 hours ago]
window=1 scan=10 would have you scan 1 out of every 10 seconds.

Daniel Spofford   [15 hours ago]
So this should be fairly easy to mitigate, darn multipurpose chips.

fhunleth   [15 hours ago]
Yep. Well, it's good that this came up. The Raspberry Pi **should** have the issue as well. In any case, you're being a good citizen by not having BT monopolize the radio.

Daniel Spofford   [15 hours ago]
I don’t see this on the RPI3 =/

fhunleth   [15 hours ago]
In the projects that I hit this on, everything was fine until we streamed big files over WiFi.

Daniel Spofford   [15 hours ago]
Hmmm yeah it is interesting because this is the same firmware across BBBW and RPI3, what is happening when I test this should be fairly identical.

Daniel Spofford   [15 hours ago]
I dropped a bunch of garbage from my linux defconfig and no longer experience this issue, without making the adjustments we discussed.

Daniel Spofford   [15 hours ago]
:upside_down_face:

Daniel Spofford   [15 hours ago]
```-CONFIG_NET=y
-CONFIG_BT=m
-CONFIG_BT_BREDR=y
-CONFIG_BT_RFCOMM=m
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=m
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_CMTP=m
-CONFIG_BT_HIDP=m
-CONFIG_BT_HS=y
-CONFIG_BT_LE=y
-CONFIG_BT_6LOWPAN=m
-CONFIG_BT_DEBUGFS=y
-
-CONFIG_BT_HCIBCM203X=m
-CONFIG_BT_HCIBFUSB=m
-CONFIG_BT_HCIBPA10X=m
-CONFIG_BT_HCIBTSDIO=m
-CONFIG_BT_HCIBTUSB=m
-CONFIG_BT_HCIBTUSB_BCM=y
-CONFIG_BT_HCIBTUSB_RTL=y
-CONFIG_BT_HCIUART=m
-CONFIG_BT_HCIUART_3WIRE=y
-CONFIG_BT_HCIUART_ATH3K=y
-CONFIG_BT_HCIUART_BCM=y
-CONFIG_BT_HCIUART_BCSP=y
-CONFIG_BT_HCIUART_H4=y
-CONFIG_BT_HCIUART_INTEL=y
-CONFIG_BT_HCIUART_LL=y
-CONFIG_BT_HCIUART_QCA=y
-CONFIG_BT_HCIVHCI=m
-
-CONFIG_BT_ATH3K=m
-CONFIG_BT_BCM=m
-CONFIG_BT_INTEL=m
-CONFIG_BT_MRVL=m
-CONFIG_BT_MRVL_SDIO=m
-CONFIG_BT_QCA=m
-CONFIG_BT_RTL=m
-CONFIG_BT_WILINK=m```

fhunleth   [2 hours ago]
Cool. The docs make it sound like coexistence is handled automatically and that would validate what you're seeing.
Pasted image at 2019-04-12, 8:32 AM 

fhunleth   [2 hours ago]
Also, it seems good to get rid of Linux BT drivers that might be interfering.

fhunleth   [2 hours ago]
Is there a way with Harald to dump information about the BT controller? Like the MAC address/BD address?

fhunleth   [2 hours ago]
It also looks like TI has a bunch of proprietary HCI commands at http://www.ti.com/lit/ug/swru442b/swru442b.pdf. The HCI_VS_Get_System_Status one might be interesting to run as a sanity check.
I’m not sure what the default is for BBBW, but you may also have to fiddle with the device tree overlays? It looks like there are a few that deal with that chip in the BB repo https://github.com/beagleboard/bb.org-overlays/blob/master/src/arm/BB-BBBW-WL1835-00A0.dts (edited) 
fhunleth [7:49 AM]
@Daniel Spofford I was looking at the Broadcom Bluetooth driver in the Linux kernel at https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git/tree/drivers/bluetooth/btbcm.c. There are a couple slightly disturbing thing. One is that the BD address indicates controller state on some chips. See https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git/tree/drivers/bluetooth/btbcm.c#n60.
The second is that there's a firmware update part. Something called the Minidrv? https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git/tree/drivers/bluetooth/btbcm.c#n104
The firmware filename is computed by querying some registers on the module. I'm not sure what the final filename is. There's only one .hcd file on the Linux firmware repo, but there might be more: https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/brcm
Also, the Linux firmware site reminded me that the Raspberry Pi 3B has a 43430 module and the 3B+ has a 43455. I could swear that there's more variation on their modules, but I need to search to verify. I'm using a Raspberry Pi 3A+ for my testing. :slightly_smiling_face:
Here's the better site for getting RPi WiFi firmware: https://github.com/LibreELEC/brcmfmac_sdio-firmware-rpi/tree/master/firmware/brcm
The comments on the .hcd files are... interesting... (I.e. "Fix Bluetooth LE issues") :scream:

fhunleth [8:02 AM]
Btw, the official Nerves systems ship with the WiFi firmware in the LibreELEC directory. We currently don't copy the `.hcd` files over. We can start doing that or copy from another repo if someplace else is more authoritative.
@fhunleth

So I just fresh cloned `verypossible/harald_example_rpi3`, then:
`MIX_TARGET=rpi3 mix do deps.get, compile --force, firmware, firmware.burn`
Then in iex: `Harald.LE.scan(:green_llama)`
Yields:
```%{
  92396358486 => %Harald.HCI.Event.LEMeta.AdvertisingReport.Device{
    address: 92396358486,
    address_type: 0,
    data: [{1, <<6>>}, {2, <<224, 255>>}]
    event_type: 0,
    rss: 181
  }
}```
So it found 1 device nearby, but it will return all devices it catches advertising. It is possible if there is a BLE device nearby you that it didn’t return that you are missing its advertisement, try `Harald.LE.scan(:green_llama, time: 30_000)` to increase the scan window to 30 seconds.

This scan should return any nearby BLE device, our `Scanning_Filter_Policy` is left on the default of `0x00` which accepts all advertising packets except directed advertising packets that are not directed at your device.

Also, note the `data` attribute above, that is the advertising data from that device. Fully supported AD Structures will come back as structs, we only fully support “Manufacturer Specific Data” and “Service Data - 32-bit UUID” right now. See https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile for a list of AD Structures with each ones id, name, and a description with a reference to the spec doc where there is more information (for AD structures, there actual structure is defined in the Core Specification Supplement (click the `8` on this page to snag that doc https://www.bluetooth.com/specifications/bluetooth-core-specification). More conveniently if you’re only interested in the id and name, you can check the `GenericAccessProfile` module in Harald.

For AD Structures that are _not_ fully supported, they come back as `{ad_structure_id, ad_structure_data}` tuples. For example, above :point_up: the `{2, <<224, 255>>}`. Checking the mappings I mentioned `2` = `"Incomplete List of 16-bit Service Class UUIDs"`, and (checking the CSS doc if you are unfamiliar with the structure of that ad structures payload) you will see that it is returning one 16 bit service UUID `<<224, 255>>`.

`:green_llama` can be any atom, it is a namespace, as long as the namespace you specify for Harald when starting it matches the namespace you provide when executing commands (like scan). (edited) 
squaresurf commented 5 years ago

Is there a TL;DR regarding the convo that we can set as the title for this issue?