From 9b191f3d26f937109d8ca65d2e50a3bc0ad3f34d Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 20 Oct 2016 14:32:36 +0700 Subject: [PATCH] add callback with dfu irq example --- Adafruit_BLEMIDI.cpp | 4 +- examples/callbacks/callbacks.ino | 17 +- examples/callbacks_dfuirq/BluefruitConfig.h | 56 ++++ .../callbacks_dfuirq/callbacks_dfuirq.ino | 242 ++++++++++++++++++ 4 files changed, 309 insertions(+), 10 deletions(-) create mode 100644 examples/callbacks_dfuirq/BluefruitConfig.h create mode 100644 examples/callbacks_dfuirq/callbacks_dfuirq.ino diff --git a/Adafruit_BLEMIDI.cpp b/Adafruit_BLEMIDI.cpp index c40f04c..65471ca 100644 --- a/Adafruit_BLEMIDI.cpp +++ b/Adafruit_BLEMIDI.cpp @@ -144,8 +144,8 @@ void Adafruit_BLEMIDI::processRxCallback(uint8_t data[], uint16_t len, Adafruit_ // First 3 bytes is always : Header + Timestamp + Status midi_header_t header; - uint16_t tstamp; - uint8_t status; + uint16_t tstamp = 0; + uint8_t status = 0; header.byte = *data++; len--; diff --git a/examples/callbacks/callbacks.ino b/examples/callbacks/callbacks.ino index 6929373..04b63fa 100644 --- a/examples/callbacks/callbacks.ino +++ b/examples/callbacks/callbacks.ino @@ -92,7 +92,7 @@ Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_ // BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST); int32_t charid_string; -int32_t charid_dec; +int32_t charid_number; // A small helper void error(const __FlashStringHelper*err) { @@ -127,11 +127,11 @@ void BleGattRX(int32_t chars_id, uint8_t data[], uint16_t len) { Serial.write(data, len); Serial.println(); - }else if (chars_id == charid_dec) + }else if (chars_id == charid_number) { int32_t val; memcpy(&val, data, len); - Serial.print(val); + Serial.println(val); } } @@ -147,7 +147,7 @@ void setup(void) delay(500); Serial.begin(115200); - Serial.println(F("Adafruit Bluefruit AT Command Example")); + Serial.println(F("Adafruit Bluefruit Callbacks Example")); Serial.println(F("-------------------------------------")); /* Initialise the module */ @@ -172,10 +172,11 @@ void setup(void) { error( F("Callback requires at least 0.7.0") ); } - + + Serial.println( F("Adding Service 0x1234 with 2 chars 0x2345 & 0x6789") ); ble.sendCommandCheckOK( F("AT+GATTADDSERVICE=uuid=0x1234") ); - ble.sendCommandWithIntReply( F("AT+GATTADDCHAR=UUID=0x2345,PROPERTIES=0x08,MIN_LEN=1,MAX_LEN=6,DATATYPE=string,VALUE=abc"), &charid_string); - ble.sendCommandWithIntReply( F("AT+GATTADDCHAR=UUID=0x3456,PROPERTIES=0x08,MIN_LEN=4,MAX_LEN=4,DATATYPE=INTEGER,VALUE=0"), &charid_dec); + ble.sendCommandWithIntReply( F("AT+GATTADDCHAR=UUID=0x2345,PROPERTIES=0x08,MIN_LEN=1,MAX_LEN=6,DATATYPE=string,DESCRIPTION=string,VALUE=abc"), &charid_string); + ble.sendCommandWithIntReply( F("AT+GATTADDCHAR=UUID=0x6789,PROPERTIES=0x08,MIN_LEN=4,MAX_LEN=4,DATATYPE=INTEGER,DESCRIPTION=number,VALUE=0"), &charid_number); ble.reset(); @@ -194,7 +195,7 @@ void setup(void) /* Only one BLE GATT function should be set, it is possible to set it multiple times for multiple Chars ID */ ble.setBleGattRxCallback(charid_string, BleGattRX); - ble.setBleGattRxCallback(charid_dec, BleGattRX); + ble.setBleGattRxCallback(charid_number, BleGattRX); } diff --git a/examples/callbacks_dfuirq/BluefruitConfig.h b/examples/callbacks_dfuirq/BluefruitConfig.h new file mode 100644 index 0000000..a7d99be --- /dev/null +++ b/examples/callbacks_dfuirq/BluefruitConfig.h @@ -0,0 +1,56 @@ +// COMMON SETTINGS +// ---------------------------------------------------------------------------------------------- +// These settings are used in both SW UART, HW UART and SPI mode +// ---------------------------------------------------------------------------------------------- +#define BUFSIZE 128 // Size of the read buffer for incoming data +#define VERBOSE_MODE true // If set to 'true' enables debug output + + +// SOFTWARE UART SETTINGS +// ---------------------------------------------------------------------------------------------- +// The following macros declare the pins that will be used for 'SW' serial. +// You should use this option if you are connecting the UART Friend to an UNO +// ---------------------------------------------------------------------------------------------- +#define BLUEFRUIT_SWUART_RXD_PIN 9 // Required for software serial! +#define BLUEFRUIT_SWUART_TXD_PIN 10 // Required for software serial! +#define BLUEFRUIT_UART_CTS_PIN 11 // Required for software serial! +#define BLUEFRUIT_UART_RTS_PIN -1 // Optional, set to -1 if unused + + +// HARDWARE UART SETTINGS +// ---------------------------------------------------------------------------------------------- +// The following macros declare the HW serial port you are using. Uncomment +// this line if you are connecting the BLE to Leonardo/Micro or Flora +// ---------------------------------------------------------------------------------------------- +#ifdef Serial1 // this makes it not complain on compilation if there's no Serial1 + #define BLUEFRUIT_HWSERIAL_NAME Serial1 +#endif + + +// SHARED UART SETTINGS +// ---------------------------------------------------------------------------------------------- +// The following sets the optional Mode pin, its recommended but not required +// ---------------------------------------------------------------------------------------------- +#define BLUEFRUIT_UART_MODE_PIN 12 // Set to -1 if unused + + +// SHARED SPI SETTINGS +// ---------------------------------------------------------------------------------------------- +// The following macros declare the pins to use for HW and SW SPI communication. +// SCK, MISO and MOSI should be connected to the HW SPI pins on the Uno when +// using HW SPI. This should be used with nRF51822 based Bluefruit LE modules +// that use SPI (Bluefruit LE SPI Friend). +// ---------------------------------------------------------------------------------------------- +#define BLUEFRUIT_SPI_CS 8 +#define BLUEFRUIT_SPI_IRQ 7 +#define BLUEFRUIT_SPI_RST 6 // Optional but recommended, set to -1 if unused + +// SOFTWARE SPI SETTINGS +// ---------------------------------------------------------------------------------------------- +// The following macros declare the pins to use for SW SPI communication. +// This should be used with nRF51822 based Bluefruit LE modules that use SPI +// (Bluefruit LE SPI Friend). +// ---------------------------------------------------------------------------------------------- +#define BLUEFRUIT_SPI_SCK 13 +#define BLUEFRUIT_SPI_MISO 12 +#define BLUEFRUIT_SPI_MOSI 11 diff --git a/examples/callbacks_dfuirq/callbacks_dfuirq.ino b/examples/callbacks_dfuirq/callbacks_dfuirq.ino new file mode 100644 index 0000000..a8fe8bf --- /dev/null +++ b/examples/callbacks_dfuirq/callbacks_dfuirq.ino @@ -0,0 +1,242 @@ +/********************************************************************* + This is an example for our nRF51822 based Bluefruit LE modules + + Pick one up today in the adafruit shop! + + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + MIT license, check LICENSE for more information + All text above, and the splash screen below must be included in + any redistribution +*********************************************************************/ + +#include +#include +#if not defined (_VARIANT_ARDUINO_DUE_X_) && not defined (_VARIANT_ARDUINO_ZERO_) +#include +#endif + +#include "Adafruit_BLE.h" +#include "Adafruit_BluefruitLE_SPI.h" +#include "Adafruit_BluefruitLE_UART.h" +#include "Adafruit_BLEGatt.h" + +#include "BluefruitConfig.h" + +/* This example demonstrates how to use Bluefruit callback API : + - setConnectCallback(), setDisconnectCallback(), setBleUartRxCallback(), + setBleGattRxCallback() are used to install callback function for specific + event. + - Furthermore, update() must be called inside loop() for callback to + be executed. + + The sketch will add an custom service with 2 writable characteristics, + and install callback to execute when there is an update from central device + - one hold string + - one hold a 4-byte integer +*/ + +/*========================================================================= + APPLICATION SETTINGS + +     FACTORYRESET_ENABLE    Perform a factory reset when running this sketch +     +     Enabling this will put your Bluefruit LE module + in a 'known good' state and clear any config + data set in previous sketches or projects, so +     running this at least once is a good idea. +     +     When deploying your project, however, you will + want to disable factory reset by setting this + value to 0.  If you are making changes to your +     Bluefruit LE device via AT commands, and those + changes aren't persisting across resets, this + is the reason why.  Factory reset will erase + the non-volatile memory where config data is + stored, setting it back to factory default + values. +         +     Some sketches that require you to bond to a + central device (HID mouse, keyboard, etc.) + won't work at all with this feature enabled + since the factory reset will clear all of the + bonding data stored on the chip, meaning the + central device won't be able to reconnect. + + MINIMUM_FIRMWARE_VERSION Minimum firmware version to have some new features + -----------------------------------------------------------------------*/ +#define FACTORYRESET_ENABLE 1 +#define MINIMUM_FIRMWARE_VERSION "0.7.1" +/*=========================================================================*/ + + + +// Create the bluefruit object, either software serial...uncomment these lines +/* + SoftwareSerial bluefruitSS = SoftwareSerial(BLUEFRUIT_SWUART_TXD_PIN, BLUEFRUIT_SWUART_RXD_PIN); + + Adafruit_BluefruitLE_UART ble(bluefruitSS, BLUEFRUIT_UART_MODE_PIN, + BLUEFRUIT_UART_CTS_PIN, BLUEFRUIT_UART_RTS_PIN); +*/ + +/* ...or hardware serial, which does not need the RTS/CTS pins. Uncomment this line */ +// Adafruit_BluefruitLE_UART ble(BLUEFRUIT_HWSERIAL_NAME, BLUEFRUIT_UART_MODE_PIN); + +/* ...hardware SPI, using SCK/MOSI/MISO hardware SPI pins and then user selected CS/IRQ/RST */ +Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST); + +/* ...software SPI, using SCK/MOSI/MISO user-defined SPI pins and then user selected CS/IRQ/RST */ +//Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_SCK, BLUEFRUIT_SPI_MISO, +// BLUEFRUIT_SPI_MOSI, BLUEFRUIT_SPI_CS, +// BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST); + +Adafruit_BLEGatt gatt(ble); + +int32_t charid_string; +int32_t charid_number; + +// Wire DFU pin to interruptable pin +int irq_pin = 3; + +// use boolean variable to signal loop() to call ble.update() +// You could call ble.update() is ISR but it will increase ISR lattency +volatile boolean irq_event_available = false; + +// A small helper +void error(const __FlashStringHelper*err) { + Serial.println(err); + while (1); +} + +void connected(void) +{ + Serial.println( F("Connected") ); +} + +void disconnected(void) +{ + Serial.println( F("Disconnected") ); +} + +void BleUartRX(char data[], uint16_t len) +{ + Serial.print( F("[BLE UART RX]" ) ); + Serial.write(data, len); + Serial.println(); +} + +void BleGattRX(int32_t chars_id, uint8_t data[], uint16_t len) +{ + Serial.print( F("[BLE GATT RX] (" ) ); + Serial.print(chars_id); + Serial.print(") "); + + if (chars_id == charid_string) + { + Serial.write(data, len); + Serial.println(); + } else if (chars_id == charid_number) + { + int32_t val; + memcpy(&val, data, len); + Serial.println(val); + } +} + +void DfuIrqHandle(void) +{ + // signal loop() to handle event + irq_event_available = true; +} + +/**************************************************************************/ +/*! + @brief Sets up the HW an the BLE module (this function is called + automatically on startup) +*/ +/**************************************************************************/ +void setup(void) +{ + while (!Serial); // required for Flora & Micro + delay(500); + + Serial.begin(115200); + Serial.println(F("Adafruit Bluefruit Callback with DFU IRQ Example")); + Serial.println(F("-------------------------------------")); + + pinMode(irq_pin, INPUT_PULLUP); + attachInterrupt(digitalPinToInterrupt(3), DfuIrqHandle, FALLING); + + /* Initialise the module */ + Serial.print(F("Initialising the Bluefruit LE module: ")); + + if ( !ble.begin(VERBOSE_MODE) ) + { + error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?")); + } + Serial.println( F("OK!") ); + + if ( FACTORYRESET_ENABLE ) + { + /* Perform a factory reset to make sure everything is in a known state */ + Serial.println(F("Performing a factory reset: ")); + if ( ! ble.factoryReset() ) { + error(F("Couldn't factory reset")); + } + } + + if ( !ble.isVersionAtLeast(MINIMUM_FIRMWARE_VERSION) ) + { + error( F("Callback with DFU Pin as IRQ requires at least 0.7.1") ); + } + + Serial.println( F("Adding Service 0x1234 with 2 chars 0x2345 & 0x6789") ); + gatt.addService(0x1234); + charid_string = gatt.addCharacteristic(0x2345, GATT_CHARS_PROPERTIES_WRITE, 1, 6, BLE_DATATYPE_STRING, "string"); + charid_number = gatt.addCharacteristic(0x6789, GATT_CHARS_PROPERTIES_WRITE, 4, 4, BLE_DATATYPE_INTEGER, "number"); + + /* Reset the device for the new service setting changes to take effect */ + Serial.print(F("Performing a SW reset (service changes require a reset): ")); + ble.reset(); + + /* Disable command echo from Bluefruit */ + ble.echo(false); + + Serial.println("Requesting Bluefruit info:"); + /* Print Bluefruit information */ + ble.info(); + + /* Change DFU Pin to IRQ mode */ + Serial.println( F("Change DFU Pin to IRQ Mode") ); + ble.sendCommandCheckOK( F("AT+DFUIRQ=on") ); + + /* Set callbacks */ + ble.setConnectCallback(connected); + ble.setDisconnectCallback(disconnected); + ble.setBleUartRxCallback(BleUartRX); + + /* Only one BLE GATT function should be set, it is possible to set it + multiple times for multiple Chars ID */ + ble.setBleGattRxCallback(charid_string, BleGattRX); + ble.setBleGattRxCallback(charid_number, BleGattRX); +} + + + +/**************************************************************************/ +/*! + @brief Constantly poll for new command or response data +*/ +/**************************************************************************/ +void loop(void) +{ + if (irq_event_available) + { + // inteval = 0 will always get executed + // Registered callbacks for the event will be fired accordingly + ble.update(0); + } +} +