Qmk_firmware: RFC: Adafruit Feather Bluetooth Low Energy support

Created on 28 Nov 2016  路  17Comments  路  Source: qmk/qmk_firmware

I took a week off work and hand-wired a keyboard using an Adafruit Feather 32u4 BLE board, then wrote BLE drivers for it(!)

The keyboard is itself relatively uninteresting: https://github.com/wez/qmk_firmware/tree/master/keyboards/iota#iota-keyboard-firmware

The BLE driver will likely want to be re-used from other boards; for example, there is also a Cortex-M0 variant of this same board, and a standalone BLE module that is addressable via SPI (and another addressable over UART).

The code for this driver is here: https://github.com/wez/qmk_firmware/blob/master/tmk_core/protocol/lufa/ble.cpp

This issue is open to figure out how to get this in a good shape for merging into the QMK repo.

Things I suspect that will be wanted:

  1. Move this to its own BLE dir, possibly renaming it to match the board (it is perhaps more accurately described as an Adafruit BLESPIFRIEND)

  2. Move the SPI code out, as it is very AVR specific right now. Also note that the SPI code in tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/Peripheral/AVR8/SPI_AVR8.h did not work for this in my first go-around. Maybe just figuring out what the difference was and resolving that is the right way to go. But also note that ChibiOS has its own SPI interface too; I think we may want to have a "proper" QMK SPI interface that does the right thing.

You can compare the branches here:
https://github.com/jackhumbert/qmk_firmware/compare/master...wez:master

It's not in the best shape for making pull requests right now; let me know roughly how you'd like to proceed and I can whip things into better shape.

Most helpful comment

If you're asking about using the SPIFRIEND, I have some code in https://github.com/wez/qmk_firmware/commit/bb836c83e604a70b304f1b5d3f715bea620aed11 that I need to break out as a PR to submit back to QMK. Companion post explaining this build is at https://www.facebook.com/notes/wez-furlong/building-a-keyboard-ii/10154296367151787

All 17 comments

Oh, I was about to start working on Adafruit BLE support. Thanks for posting this at the right moment :+1: .

My suggestions after a quick glance over your code:

  • Pin assignment defines should be moved to keyboard config.h, and not hardcoded in ble.cpp. Hardcoded B1, B2 and B3 should changed to defines.
  • Change the enable flag to ADAFRUIT_BLE_SPI_ENABLE=on
  • Rename from ble.cpp to adafruit_ble.cpp, and maybe ringbuffer.hpp to adafruit_ble_ringbuffer.hpp, and place it in the same directory. I feel these are self contained enough and can be added in a single pull request.
  • The changes in lufa.c is more radical. I prefer we create a framework where user can choose the desired output by hitting a key.

Oh, I notice you are getting ready for M0 version of the Adafruit controller. Did you manage to make it work? The problem with 32u4 is that space is limited and I'm left with only about 4KB, not including BLE support.

re: M0, I have one on order. During development I hit some pretty miserable latency issues with this module that I attributed to bad firmware on the Nordic BLE module (which is itself an M0). I thought that I would have to work on the firmware of that piece to straighten them out, so I ordered the M0 flavor board + a hardware debugging kit to program the Nordic board.

I figured out today that I could tweak the advertising intervals to solve the latency problems, so I didn't strictly need this other board, but decided that I'd take it anyway; I'm butting up pretty close to the 28k limit (4k bootloader) on the 32u4, and I think I may have run out of ram a couple of times during testing before I figured out how to use PSTR.

So... TL;DR, I want to get things working on the M0. I envision that this is mostly just a matter of calling the ChibiOS SPI driver in place of the inlined AVR code in there, and that most of the effort will be me fixing up the rest of the code in my keyboard build to drop in the M0 board (there's some I2C and pin assignment stuff to clean up there).

@wez I figure with your OLED matrix, you are going to run out of space very soon. With my board and keymap, I only have about 5 KB left before BLE and whatever else I'm going to implement.

About M0, you might want to read https://github.com/tmk/tmk_keyboard/issues/338

for the OLED, I cheat: I only store the character codes, not the full bitmap. That means that rather than 512 bytes I need only need 88.

For the M0; the HAL stuff doesn't look too complicated to flesh out; it should just be a matter of mapping the pins and so on (famous last words?)

Re: size, this is the build with BLE:

Size before:
   text    data     bss     dec     hex filename
      0   26108       0   26108    65fc iota_avr_default.hex

this is with it turned off:

Size after:
   text    data     bss     dec     hex filename
      0   21950       0   21950    55be iota_avr_default.hex

so that's 4158 difference. Just enough room for you? :-)

For the M0; the HAL stuff doesn't look too complicated to flesh out; it should just be a matter of mapping the pins and so on (famous last words?)

I'm afraid those stuff are far beyond my pay grade, but if you are able to make the M0 work, why not work directly with nRF51/52? For example, using this or this.

so that's 4158 difference

That is tight, but should be just enough. I'll try integrating your code in my firmware. Thanks.

Oh, that board on tindie is pretty compelling. It has enough IO on board that it can manage a reasonable size matrix with some pins to spare. Sounds like you'll need a SWD kit to do anything with it though, which raises the bar a bit: the cheapest I could find with some casual browsing was this. The sparkfun board feels more awkward despite the more appealing price point: no USB so you'd need either an FTDI or SWD programmer, and you'd need to add a battery and charging circuit.

What I'm really interested in for my next build is split wireless; I don't think there is support for running one of these nRF chips simultaneously in peripheral and central role yet, so this may end being relativey expensive and need 3 RF chips; the halves talking to each other using two of them (maybe these?) and then one of the halves acting as a as BLE.

Has any progress happened on being able to use one of the nrf chips directly over uart/spi instead of an ezkey/feather?

SPI should work right now, at least if you use the same pin assignment as Feather.

If you're asking about using the SPIFRIEND, I have some code in https://github.com/wez/qmk_firmware/commit/bb836c83e604a70b304f1b5d3f715bea620aed11 that I need to break out as a PR to submit back to QMK. Companion post explaining this build is at https://www.facebook.com/notes/wez-furlong/building-a-keyboard-ii/10154296367151787

Does anyone have issues with the left and right click (KC_BTN1 and KC_BTN2) not working for mousekeys? Seems to only work via USB.

@sungjp I don't think there's any code for mouse button clicks in there yet(!) Shouldn't be too hard to add, but I'm not looking at that any time soon; want to try putting together a PR for that? I'd be happy to review it!

@wez Thanks for telling me. I'll look into it after final exam week is over. Sounds fun to tackle :)

Turned out that I had implemented this locally, but not pushed it yet; https://github.com/wez/qmk_firmware/commit/73b7a1447041f3dde4caf07aaf608696974f9f9a is the commit with the changes; the main things you needs are in the tmk_core/protocol/lufa/adafruit_ble.cpp file

Works great! Thanks!

I believe #1342 implements this, so if I'm wrong please feel free to reopen this. :D

hi, I am using adafruit feather 32u4 on my board. the board is functioning pretty much great. the only issue is that when both Bluetooth and USB are connected, the signal are being sent on both the interface.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jetpacktuxedo picture jetpacktuxedo  路  3Comments

vokeio picture vokeio  路  3Comments

jacwib picture jacwib  路  3Comments

MarkuBu picture MarkuBu  路  3Comments

Frefreak picture Frefreak  路  4Comments