Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Added support for the Adafruit Feather M0 Bluefruit LE (and potential…
…ly other Bluefruit LE boards/modules that communicate with the nRF51822 via SPI) to StandardFirmataBLE
  • Loading branch information
cstawarz committed Mar 27, 2018
commit c2e8da390e59f1093227cb9549c720f3290d7f8c
2 changes: 1 addition & 1 deletion examples/StandardFirmataBLE/StandardFirmataBLE.ino
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,7 @@ void setup()
Firmata.attach(START_SYSEX, sysexCallback);
Firmata.attach(SYSTEM_RESET, systemResetCallback);

#ifdef BLE_REQ
#ifdef IS_IGNORE_BLE_PINS
for (byte i = 0; i < TOTAL_PINS; i++) {
if (IS_IGNORE_BLE_PINS(i)) {
Firmata.setPinMode(i, PIN_MODE_IGNORE);
Expand Down
34 changes: 34 additions & 0 deletions examples/StandardFirmataBLE/bleConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* - Arduino 101 (recommended)
* - RedBearLab BLE Shield (v2) ** to be verified **
* - RedBearLab BLE Nano ** works with modifications **
* - Adafruit Feather M0 Bluefruit LE
*
*================================================================================================*/

Expand Down Expand Up @@ -58,6 +59,31 @@
#endif


/*
* Adafruit Feather M0 Bluefruit LE
*
* If you are using an Adafruit Feather M0 Bluefruit LE, uncomment the define below.
* This configuration should also work with other Bluefruit LE boards/modules that communicate
* with the nRF51822 via SPI (e.g. Bluefruit LE SPI Friend, Bluefruit LE Shield), although
* you may need to change the values of BLE_SPI_CS, BLE_SPI_IRQ, and/or BLE_SPI_RST below.
*
* You will need to install a lightly-modified version of the Adafruit BluefruitLE nRF51
* package, available at:
* https://github.com/cstawarz/Adafruit_BluefruitLE_nRF51/archive/firmata_fixes.zip
*/
//#define BLUEFRUIT_LE_SPI

#ifdef BLUEFRUIT_LE_SPI
// Both values must be between 10ms and 4s
#define FIRMATA_BLE_MIN_INTERVAL 10 // 10ms
#define FIRMATA_BLE_MAX_INTERVAL 20 // 20ms

#define BLE_SPI_CS 8
#define BLE_SPI_IRQ 7
#define BLE_SPI_RST 4
#endif


/*
* Generic settings
*/
Expand Down Expand Up @@ -93,6 +119,12 @@ BLEStream stream(BLE_REQ, BLE_RDY, BLE_RST);
#endif


#ifdef BLUEFRUIT_LE_SPI
#include "utility/BluefruitLE_SPI_Stream.h"
BluefruitLE_SPI_Stream stream(BLE_SPI_CS, BLE_SPI_IRQ, BLE_SPI_RST);
#endif


/*
* RedBearLab BLE Nano (with default switch settings)
*
Expand Down Expand Up @@ -133,4 +165,6 @@ BLEStream stream(BLE_REQ, BLE_RDY, BLE_RST);

#if defined(BLE_REQ) && defined(BLE_RDY) && defined(BLE_RST)
#define IS_IGNORE_BLE_PINS(p) ((p) == BLE_REQ || (p) == BLE_RDY || (p) == BLE_RST)
#elif defined(BLE_SPI_CS) && defined(BLE_SPI_IRQ) && defined(BLE_SPI_RST)
#define IS_IGNORE_BLE_PINS(p) ((p) == BLE_SPI_CS || (p) == BLE_SPI_IRQ || (p) == BLE_SPI_RST)
#endif
3 changes: 3 additions & 0 deletions utility/BluefruitLE_SPI_Stream.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/*
* Implementation is in BluefruitLE_SPI_Stream.h to avoid linker issues.
*/
127 changes: 127 additions & 0 deletions utility/BluefruitLE_SPI_Stream.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
BluefruitLE_SPI_Stream.h

Documentation for the various AT commands used below is available at
https://learn.adafruit.com/adafruit-feather-m0-bluefruit-le/at-commands
*/

#ifndef _BLUEFRUIT_LE_SPI_STREAM_H_
#define _BLUEFRUIT_LE_SPI_STREAM_H_

#include <Adafruit_BluefruitLE_SPI.h>


class BluefruitLE_SPI_Stream : public Stream
{
public:
BluefruitLE_SPI_Stream(int8_t csPin, int8_t irqPin, int8_t rstPin);

void begin();
bool poll();
void end();

// Print overrides
size_t write(uint8_t byte);
using Print::write; // Expose other write variants

// Stream overrides
int available();
int read();
int peek();
void flush();

private:
Adafruit_BluefruitLE_SPI ble;

uint8_t txBuffer[SDEP_MAX_PACKETSIZE];
size_t txCount;
};


BluefruitLE_SPI_Stream::BluefruitLE_SPI_Stream(int8_t csPin, int8_t irqPin, int8_t rstPin) :
ble(csPin, irqPin, rstPin),
txCount(0)
{ }

void BluefruitLE_SPI_Stream::begin()
{
// Initialize the SPI interface
ble.begin();

// Perform a factory reset to make sure everything is in a known state
ble.factoryReset();

// Disable command echo from Bluefruit
ble.echo(false);

// Change the MODE LED to indicate BLE UART activity
ble.println("AT+HWMODELED=BLEUART");

// Set local name
ble.print("AT+GAPDEVNAME=");
ble.println(FIRMATA_BLE_LOCAL_NAME);

// Set connection interval
ble.print("AT+GAPINTERVALS=");
ble.print(FIRMATA_BLE_MIN_INTERVAL);
ble.print(",");
ble.print(FIRMATA_BLE_MAX_INTERVAL);
ble.println(",,,");

// Disable real and simulated mode switch (i.e. "+++") command
ble.println("AT+MODESWITCHEN=local,0");
ble.enableModeSwitchCommand(false);

// Switch to data mode
ble.setMode(BLUEFRUIT_MODE_DATA);
}

bool BluefruitLE_SPI_Stream::poll()
{
// If there's outgoing data in the buffer, just send it. The firmware on
// the nRF51822 will decide when to transmit the data in its TX FIFO.
if (txCount) flush();

// In order to check for a connection, we would need to switch from data to
// command mode and back again. However, due to the internal workings of
// Adafruit_BluefruitLE_SPI, this can lead to unread incoming data being
// lost. Therefore, we always return true.
return true;
}

void BluefruitLE_SPI_Stream::end()
{
flush();
ble.end();
}

size_t BluefruitLE_SPI_Stream::write(uint8_t byte)
{
txBuffer[txCount++] = byte;
if (txCount == sizeof(txBuffer)) flush();
return 1;
}

int BluefruitLE_SPI_Stream::available()
{
return ble.available();
}

int BluefruitLE_SPI_Stream::read()
{
return ble.read();
}

int BluefruitLE_SPI_Stream::peek()
{
return ble.peek();
}

void BluefruitLE_SPI_Stream::flush()
{
ble.write(txBuffer, txCount);
txCount = 0;
}


#endif // _BLUEFRUIT_LE_SPI_STREAM_H_