Bluetooth UART support for the Adafruit BluefruitLE SPI, for the University of York Engineering Stage 1 project

Committer:
ajp109
Date:
Fri Mar 12 14:35:25 2021 +0000
Revision:
3:bdfd15be7b82
Parent:
1:6ff0eee2da9c
Remove readme

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ajp109 0:a80552d32b80 1 /**************************************************************************/
ajp109 0:a80552d32b80 2 /*!
ajp109 0:a80552d32b80 3 @file Adafruit_BLE.c
ajp109 0:a80552d32b80 4 @author hathach (Adafruit Industries), ajp109 (University of York)
ajp109 0:a80552d32b80 5
ajp109 0:a80552d32b80 6 @section LICENSE
ajp109 0:a80552d32b80 7
ajp109 0:a80552d32b80 8 Software License Agreement (BSD License)
ajp109 0:a80552d32b80 9
ajp109 0:a80552d32b80 10 Copyright (c) 2014, Adafruit Industries (adafruit.com)
ajp109 0:a80552d32b80 11 All rights reserved.
ajp109 0:a80552d32b80 12
ajp109 0:a80552d32b80 13 Redistribution and use in source and binary forms, with or without
ajp109 0:a80552d32b80 14 modification, are permitted provided that the following conditions are met:
ajp109 0:a80552d32b80 15 1. Redistributions of source code must retain the above copyright
ajp109 0:a80552d32b80 16 notice, this list of conditions and the following disclaimer.
ajp109 0:a80552d32b80 17 2. Redistributions in binary form must reproduce the above copyright
ajp109 0:a80552d32b80 18 notice, this list of conditions and the following disclaimer in the
ajp109 0:a80552d32b80 19 documentation and/or other materials provided with the distribution.
ajp109 0:a80552d32b80 20 3. Neither the name of the copyright holders nor the
ajp109 0:a80552d32b80 21 names of its contributors may be used to endorse or promote products
ajp109 0:a80552d32b80 22 derived from this software without specific prior written permission.
ajp109 0:a80552d32b80 23
ajp109 0:a80552d32b80 24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
ajp109 0:a80552d32b80 25 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
ajp109 0:a80552d32b80 26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
ajp109 0:a80552d32b80 27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
ajp109 0:a80552d32b80 28 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
ajp109 0:a80552d32b80 29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
ajp109 0:a80552d32b80 30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ajp109 0:a80552d32b80 31 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
ajp109 0:a80552d32b80 32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
ajp109 0:a80552d32b80 33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ajp109 0:a80552d32b80 34 */
ajp109 0:a80552d32b80 35 /**************************************************************************/
ajp109 0:a80552d32b80 36 #include "Adafruit_BLE.h"
ajp109 0:a80552d32b80 37
ajp109 0:a80552d32b80 38 #ifndef min
ajp109 0:a80552d32b80 39 #define min(a,b) ((a) < (b) ? (a) : (b))
ajp109 0:a80552d32b80 40 #endif
ajp109 0:a80552d32b80 41
ajp109 0:a80552d32b80 42 enum {
ajp109 0:a80552d32b80 43 EVENT_SYSTEM_CONNECT = 0,
ajp109 0:a80552d32b80 44 EVENT_SYSTEM_DISCONNECT = 1,
ajp109 0:a80552d32b80 45
ajp109 0:a80552d32b80 46 EVENT_SYSTEM_BLE_UART_RX = 8,
ajp109 0:a80552d32b80 47 // 9 reserved
ajp109 0:a80552d32b80 48 };
ajp109 0:a80552d32b80 49
ajp109 0:a80552d32b80 50 enum {
ajp109 0:a80552d32b80 51 NVM_USERDATA_SIZE = 256
ajp109 0:a80552d32b80 52 };
ajp109 0:a80552d32b80 53
ajp109 0:a80552d32b80 54 /******************************************************************************/
ajp109 0:a80552d32b80 55 /*!
ajp109 0:a80552d32b80 56 @brief Constructor
ajp109 0:a80552d32b80 57 */
ajp109 0:a80552d32b80 58 /******************************************************************************/
ajp109 0:a80552d32b80 59 Adafruit_BLE::Adafruit_BLE(void)
ajp109 0:a80552d32b80 60 {
ajp109 0:a80552d32b80 61 _timeout = BLE_DEFAULT_TIMEOUT;
ajp109 0:a80552d32b80 62
ajp109 0:a80552d32b80 63 _disconnect_callback = NULL;
ajp109 0:a80552d32b80 64 _connect_callback = NULL;
ajp109 0:a80552d32b80 65 _ble_uart_rx_callback = NULL;
ajp109 0:a80552d32b80 66 _ble_gatt_rx_callback = NULL;
ajp109 0:a80552d32b80 67 }
ajp109 0:a80552d32b80 68
ajp109 0:a80552d32b80 69 /******************************************************************************/
ajp109 0:a80552d32b80 70 /*!
ajp109 0:a80552d32b80 71 @brief Helper to install callback
ajp109 0:a80552d32b80 72 @param
ajp109 0:a80552d32b80 73 */
ajp109 0:a80552d32b80 74 /******************************************************************************/
ajp109 0:a80552d32b80 75 void Adafruit_BLE::install_callback(bool enable, int8_t system_id, int8_t gatts_id)
ajp109 0:a80552d32b80 76 {
ajp109 0:a80552d32b80 77 uint8_t current_mode = _mode;
ajp109 0:a80552d32b80 78
ajp109 0:a80552d32b80 79 // switch mode if necessary to execute command
ajp109 0:a80552d32b80 80 if ( current_mode == BLUEFRUIT_MODE_DATA ) setMode(BLUEFRUIT_MODE_COMMAND);
ajp109 0:a80552d32b80 81
ajp109 0:a80552d32b80 82 this->printf( enable ? F("AT+EVENTENABLE=0x") : F("AT+EVENTDISABLE=0x") );
ajp109 0:a80552d32b80 83 this->printf( "%x", (system_id < 0) ? 0 : 1<<system_id );
ajp109 0:a80552d32b80 84
ajp109 0:a80552d32b80 85 if ( gatts_id >= 0 ) {
Andy Pomfret 1:6ff0eee2da9c 86 this->printf( ",0x%x\r\n", 1<<gatts_id );
ajp109 0:a80552d32b80 87 }
ajp109 0:a80552d32b80 88
Andy Pomfret 1:6ff0eee2da9c 89 this->printf("\r\n");
ajp109 0:a80552d32b80 90
ajp109 0:a80552d32b80 91 waitForOK();
ajp109 0:a80552d32b80 92
ajp109 0:a80552d32b80 93 // switch back if necessary
ajp109 0:a80552d32b80 94 if ( current_mode == BLUEFRUIT_MODE_DATA ) setMode(BLUEFRUIT_MODE_DATA);
ajp109 0:a80552d32b80 95 }
ajp109 0:a80552d32b80 96
ajp109 0:a80552d32b80 97 /******************************************************************************/
ajp109 0:a80552d32b80 98 /*!
ajp109 0:a80552d32b80 99 @brief Performs a system reset using AT command
ajp109 0:a80552d32b80 100 @param blocking blocking until bluefruit is ready, will take 1 second mostly
ajp109 0:a80552d32b80 101 */
ajp109 0:a80552d32b80 102 /******************************************************************************/
ajp109 0:a80552d32b80 103 bool Adafruit_BLE::reset(bool blocking)
ajp109 0:a80552d32b80 104 {
ajp109 0:a80552d32b80 105 bool isOK;
ajp109 0:a80552d32b80 106 // println();
ajp109 0:a80552d32b80 107 for (uint8_t t=0; t < 5; t++) {
ajp109 0:a80552d32b80 108 isOK = atcommand(F("ATZ"));
ajp109 0:a80552d32b80 109
ajp109 0:a80552d32b80 110 if (isOK) break;
ajp109 0:a80552d32b80 111 }
ajp109 0:a80552d32b80 112
ajp109 0:a80552d32b80 113 if (! isOK) {
ajp109 0:a80552d32b80 114 // ok we're going to get desperate
ajp109 0:a80552d32b80 115 thread_sleep_for(50);
ajp109 0:a80552d32b80 116 setMode(BLUEFRUIT_MODE_COMMAND);
ajp109 0:a80552d32b80 117 thread_sleep_for(50);
ajp109 0:a80552d32b80 118
ajp109 0:a80552d32b80 119 for (uint8_t t=0; t < 5; t++) {
ajp109 0:a80552d32b80 120 isOK = atcommand(F("ATZ"));
ajp109 0:a80552d32b80 121
ajp109 0:a80552d32b80 122 if (isOK) break;
ajp109 0:a80552d32b80 123 }
ajp109 0:a80552d32b80 124
ajp109 0:a80552d32b80 125 if (!isOK) return false;
ajp109 0:a80552d32b80 126 }
ajp109 0:a80552d32b80 127
ajp109 0:a80552d32b80 128 _reset_started_timestamp = Kernel::Clock::now();
ajp109 0:a80552d32b80 129
ajp109 0:a80552d32b80 130 // Bluefruit need 1 second to reboot
ajp109 0:a80552d32b80 131 if (blocking) {
ajp109 0:a80552d32b80 132 thread_sleep_for(1000);
ajp109 0:a80552d32b80 133 }
ajp109 0:a80552d32b80 134
ajp109 0:a80552d32b80 135 // flush all left over
ajp109 0:a80552d32b80 136 sync();
ajp109 0:a80552d32b80 137
ajp109 0:a80552d32b80 138 return isOK;
ajp109 0:a80552d32b80 139 }
ajp109 0:a80552d32b80 140
ajp109 0:a80552d32b80 141 /******************************************************************************/
ajp109 0:a80552d32b80 142 /*!
ajp109 0:a80552d32b80 143 @brief Performs a factory reset
ajp109 0:a80552d32b80 144 */
ajp109 0:a80552d32b80 145 /******************************************************************************/
ajp109 0:a80552d32b80 146 bool Adafruit_BLE::factoryReset(bool blocking)
ajp109 0:a80552d32b80 147 {
Andy Pomfret 1:6ff0eee2da9c 148 printf( "AT+FACTORYRESET\r\n" );
ajp109 0:a80552d32b80 149 bool isOK = waitForOK();
ajp109 0:a80552d32b80 150
ajp109 0:a80552d32b80 151 _reset_started_timestamp = Kernel::Clock::now();
ajp109 0:a80552d32b80 152
ajp109 0:a80552d32b80 153 // Bluefruit need 1 second to reboot
ajp109 0:a80552d32b80 154 if (blocking) {
ajp109 0:a80552d32b80 155 thread_sleep_for(1000);
ajp109 0:a80552d32b80 156 }
ajp109 0:a80552d32b80 157
ajp109 0:a80552d32b80 158 // flush all left over
ajp109 0:a80552d32b80 159 sync();
ajp109 0:a80552d32b80 160
ajp109 0:a80552d32b80 161 return isOK;
ajp109 0:a80552d32b80 162 }
ajp109 0:a80552d32b80 163
ajp109 0:a80552d32b80 164 /******************************************************************************/
ajp109 0:a80552d32b80 165 /*!
ajp109 0:a80552d32b80 166 @brief Check if the reset process is completed, should be used if user
ajp109 0:a80552d32b80 167 reset Bluefruit with non-blocking aka reset(false)
ajp109 0:a80552d32b80 168 */
ajp109 0:a80552d32b80 169 /******************************************************************************/
ajp109 0:a80552d32b80 170 bool Adafruit_BLE::resetCompleted(void)
ajp109 0:a80552d32b80 171 {
ajp109 0:a80552d32b80 172 return Kernel::Clock::now() > (_reset_started_timestamp + 1s);
ajp109 0:a80552d32b80 173 }
ajp109 0:a80552d32b80 174
ajp109 0:a80552d32b80 175 /******************************************************************************/
ajp109 0:a80552d32b80 176 /*!
ajp109 0:a80552d32b80 177 @brief Enable or disable AT Command echo from Bluefruit
ajp109 0:a80552d32b80 178
ajp109 0:a80552d32b80 179 @parma[in] enable
ajp109 0:a80552d32b80 180 true to enable (default), false to disable
ajp109 0:a80552d32b80 181 */
ajp109 0:a80552d32b80 182 /******************************************************************************/
ajp109 0:a80552d32b80 183 bool Adafruit_BLE::echo(bool enable)
ajp109 0:a80552d32b80 184 {
ajp109 0:a80552d32b80 185 return atcommand(F("ATE"), (int32_t) enable);
ajp109 0:a80552d32b80 186 }
ajp109 0:a80552d32b80 187
ajp109 0:a80552d32b80 188 /******************************************************************************/
ajp109 0:a80552d32b80 189 /*!
ajp109 0:a80552d32b80 190 @brief Check connection state, returns true is connected!
ajp109 0:a80552d32b80 191 */
ajp109 0:a80552d32b80 192 /******************************************************************************/
ajp109 0:a80552d32b80 193 bool Adafruit_BLE::isConnected(void)
ajp109 0:a80552d32b80 194 {
ajp109 0:a80552d32b80 195 int32_t connected = 0;
ajp109 0:a80552d32b80 196 atcommandIntReply(F("AT+GAPGETCONN"), &connected);
ajp109 0:a80552d32b80 197 return connected;
ajp109 0:a80552d32b80 198 }
ajp109 0:a80552d32b80 199
ajp109 0:a80552d32b80 200 /******************************************************************************/
ajp109 0:a80552d32b80 201 /*!
ajp109 0:a80552d32b80 202 @brief Disconnect if currently connected
ajp109 0:a80552d32b80 203 */
ajp109 0:a80552d32b80 204 /******************************************************************************/
ajp109 0:a80552d32b80 205 void Adafruit_BLE::disconnect(void)
ajp109 0:a80552d32b80 206 {
ajp109 0:a80552d32b80 207 atcommand( F("AT+GAPDISCONNECT") );
ajp109 0:a80552d32b80 208 }
ajp109 0:a80552d32b80 209
ajp109 0:a80552d32b80 210 /******************************************************************************/
ajp109 0:a80552d32b80 211 /*!
ajp109 0:a80552d32b80 212 @brief Print Bluefruit's information retrieved by ATI command
ajp109 0:a80552d32b80 213 */
ajp109 0:a80552d32b80 214 /******************************************************************************/
ajp109 0:a80552d32b80 215 void Adafruit_BLE::info(void)
ajp109 0:a80552d32b80 216 {
ajp109 0:a80552d32b80 217 uint8_t current_mode = _mode;
ajp109 0:a80552d32b80 218
ajp109 0:a80552d32b80 219 bool v = _verbose;
ajp109 0:a80552d32b80 220 _verbose = false;
ajp109 0:a80552d32b80 221
ajp109 0:a80552d32b80 222 ::printf("----------------\n");
ajp109 0:a80552d32b80 223
ajp109 0:a80552d32b80 224 // switch mode if necessary to execute command
ajp109 0:a80552d32b80 225 if ( current_mode == BLUEFRUIT_MODE_DATA ) setMode(BLUEFRUIT_MODE_COMMAND);
ajp109 0:a80552d32b80 226
Andy Pomfret 1:6ff0eee2da9c 227 this->printf("ATI\r\n");
ajp109 0:a80552d32b80 228
ajp109 0:a80552d32b80 229 while ( readline() ) {
ajp109 0:a80552d32b80 230 if ( !strcmp(buffer, "OK") || !strcmp(buffer, "ERROR") ) break;
ajp109 0:a80552d32b80 231 ::printf("%s", buffer);
ajp109 0:a80552d32b80 232 }
ajp109 0:a80552d32b80 233
ajp109 0:a80552d32b80 234 // switch back if necessary
ajp109 0:a80552d32b80 235 if ( current_mode == BLUEFRUIT_MODE_DATA ) setMode(BLUEFRUIT_MODE_DATA);
ajp109 0:a80552d32b80 236
ajp109 0:a80552d32b80 237 ::printf("----------------\n");
ajp109 0:a80552d32b80 238
ajp109 0:a80552d32b80 239 _verbose = v;
ajp109 0:a80552d32b80 240 }
ajp109 0:a80552d32b80 241
ajp109 0:a80552d32b80 242 /**************************************************************************/
ajp109 0:a80552d32b80 243 /*!
ajp109 0:a80552d32b80 244 @brief Checks if firmware is equal or later than specified version
ajp109 0:a80552d32b80 245 */
ajp109 0:a80552d32b80 246 /**************************************************************************/
ajp109 0:a80552d32b80 247 bool Adafruit_BLE::isVersionAtLeast(const char * versionString)
ajp109 0:a80552d32b80 248 {
ajp109 0:a80552d32b80 249 uint8_t current_mode = _mode;
ajp109 0:a80552d32b80 250
ajp109 0:a80552d32b80 251 // switch mode if necessary to execute command
ajp109 0:a80552d32b80 252 if ( current_mode == BLUEFRUIT_MODE_DATA ) setMode(BLUEFRUIT_MODE_COMMAND);
ajp109 0:a80552d32b80 253
ajp109 0:a80552d32b80 254 // requesting version number
Andy Pomfret 1:6ff0eee2da9c 255 this->printf("ATI=4\r\n");
ajp109 0:a80552d32b80 256
ajp109 0:a80552d32b80 257 readline();
ajp109 0:a80552d32b80 258 bool result = ( strcmp(buffer, versionString) >= 0 );
ajp109 0:a80552d32b80 259 waitForOK();
ajp109 0:a80552d32b80 260
ajp109 0:a80552d32b80 261 // switch back if necessary
ajp109 0:a80552d32b80 262 if ( current_mode == BLUEFRUIT_MODE_DATA ) setMode(BLUEFRUIT_MODE_DATA);
ajp109 0:a80552d32b80 263
ajp109 0:a80552d32b80 264 return result;
ajp109 0:a80552d32b80 265 }
ajp109 0:a80552d32b80 266
ajp109 0:a80552d32b80 267 /******************************************************************************/
ajp109 0:a80552d32b80 268 /*!
ajp109 0:a80552d32b80 269 @brief Get (multiple) lines of response data into internal buffer.
ajp109 0:a80552d32b80 270
ajp109 0:a80552d32b80 271 @param[in] period_ms
ajp109 0:a80552d32b80 272 period in milliseconds between each event scanning
ajp109 0:a80552d32b80 273 @return None
ajp109 0:a80552d32b80 274 */
ajp109 0:a80552d32b80 275 /******************************************************************************/
ajp109 0:a80552d32b80 276 void Adafruit_BLE::update(uint32_t period_ms)
ajp109 0:a80552d32b80 277 {
ajp109 0:a80552d32b80 278 static TimeoutTimer tt;
ajp109 0:a80552d32b80 279
ajp109 0:a80552d32b80 280 if ( tt.expired() ) {
ajp109 0:a80552d32b80 281 tt.set(period_ms);
ajp109 0:a80552d32b80 282
ajp109 0:a80552d32b80 283 bool v = _verbose;
ajp109 0:a80552d32b80 284 _verbose = false;
ajp109 0:a80552d32b80 285
ajp109 0:a80552d32b80 286 uint8_t current_mode = _mode;
ajp109 0:a80552d32b80 287
ajp109 0:a80552d32b80 288 // switch mode if necessary to execute command
ajp109 0:a80552d32b80 289 if ( current_mode == BLUEFRUIT_MODE_DATA ) setMode(BLUEFRUIT_MODE_COMMAND);
ajp109 0:a80552d32b80 290
Andy Pomfret 1:6ff0eee2da9c 291 this->printf( "AT+EVENTSTATUS\r\n" );
ajp109 0:a80552d32b80 292 readline();
ajp109 0:a80552d32b80 293 waitForOK();
ajp109 0:a80552d32b80 294
ajp109 0:a80552d32b80 295 // parse event status system_event, gatts_event
ajp109 0:a80552d32b80 296 uint8_t tempbuf[BLE_BUFSIZE+1];
ajp109 0:a80552d32b80 297 uint32_t system_event, gatts_event;
ajp109 0:a80552d32b80 298 char * p_comma = NULL;
ajp109 0:a80552d32b80 299
ajp109 0:a80552d32b80 300 system_event = strtoul(this->buffer, &p_comma, 16);
ajp109 0:a80552d32b80 301 gatts_event = strtoul(p_comma+1, NULL, 16);
ajp109 0:a80552d32b80 302
ajp109 0:a80552d32b80 303 //--------------------------------------------------------------------+
ajp109 0:a80552d32b80 304 // System Event
ajp109 0:a80552d32b80 305 //--------------------------------------------------------------------+
ajp109 0:a80552d32b80 306 if ( this->_connect_callback && (system_event & (1<<EVENT_SYSTEM_CONNECT)) ) this->_connect_callback();
ajp109 0:a80552d32b80 307 if ( this->_disconnect_callback && (system_event & (1<<EVENT_SYSTEM_DISCONNECT)) ) this->_disconnect_callback();
ajp109 0:a80552d32b80 308
ajp109 0:a80552d32b80 309 if ( this->_ble_uart_rx_callback && (system_event & (1<<EVENT_SYSTEM_BLE_UART_RX)) ) {
ajp109 0:a80552d32b80 310 // _verbose = true;
Andy Pomfret 1:6ff0eee2da9c 311 this->printf( "AT+BLEUARTRX\r\n" );
ajp109 0:a80552d32b80 312 uint16_t len = readline(tempbuf, BLE_BUFSIZE);
ajp109 0:a80552d32b80 313 waitForOK();
ajp109 0:a80552d32b80 314
ajp109 0:a80552d32b80 315 this->_ble_uart_rx_callback( (char*) tempbuf, len);
ajp109 0:a80552d32b80 316 }
ajp109 0:a80552d32b80 317
ajp109 0:a80552d32b80 318 //--------------------------------------------------------------------+
ajp109 0:a80552d32b80 319 // Gatt Event
ajp109 0:a80552d32b80 320 //--------------------------------------------------------------------+
ajp109 0:a80552d32b80 321 if ( this->_ble_gatt_rx_callback && gatts_event ) {
ajp109 0:a80552d32b80 322 // _verbose = true;
ajp109 0:a80552d32b80 323 for(uint8_t charid=1; charid < 30; charid++) {
ajp109 0:a80552d32b80 324 if ( gatts_event & (1<<(charid-1)) ) {
Andy Pomfret 1:6ff0eee2da9c 325 this->printf( "AT+GATTCHARRAW=%hhu\r\n", charid ); // use RAW command version
ajp109 0:a80552d32b80 326
ajp109 0:a80552d32b80 327 uint16_t len = readraw(); // readraw swallow OK/ERROR already
ajp109 0:a80552d32b80 328 memcpy(tempbuf, this->buffer, len);
ajp109 0:a80552d32b80 329
ajp109 0:a80552d32b80 330 this->_ble_gatt_rx_callback(charid, tempbuf, len);
ajp109 0:a80552d32b80 331 }
ajp109 0:a80552d32b80 332 }
ajp109 0:a80552d32b80 333 }
ajp109 0:a80552d32b80 334
ajp109 0:a80552d32b80 335 // switch back if necessary
ajp109 0:a80552d32b80 336 if ( current_mode == BLUEFRUIT_MODE_DATA ) setMode(BLUEFRUIT_MODE_DATA);
ajp109 0:a80552d32b80 337
ajp109 0:a80552d32b80 338 _verbose = v;
ajp109 0:a80552d32b80 339 }
ajp109 0:a80552d32b80 340 }
ajp109 0:a80552d32b80 341
ajp109 0:a80552d32b80 342 /******************************************************************************/
ajp109 0:a80552d32b80 343 /*!
ajp109 0:a80552d32b80 344 @brief Set custom ADV data packet
ajp109 0:a80552d32b80 345 @param
ajp109 0:a80552d32b80 346 */
ajp109 0:a80552d32b80 347 /******************************************************************************/
ajp109 0:a80552d32b80 348 bool Adafruit_BLE::setAdvData(uint8_t advdata[], uint8_t size)
ajp109 0:a80552d32b80 349 {
ajp109 0:a80552d32b80 350 return this->atcommand(F("AT+GAPSETADVDATA"), advdata, size);
ajp109 0:a80552d32b80 351 }
ajp109 0:a80552d32b80 352
ajp109 0:a80552d32b80 353 /******************************************************************************/
ajp109 0:a80552d32b80 354 /*!
ajp109 0:a80552d32b80 355 @brief Save user information to NVM section, current size limit is 256 bytes
ajp109 0:a80552d32b80 356 @param data buffer holding data
ajp109 0:a80552d32b80 357 @param size number of bytes
ajp109 0:a80552d32b80 358 @param offset relative offset in the NVM section
ajp109 0:a80552d32b80 359 */
ajp109 0:a80552d32b80 360 /******************************************************************************/
ajp109 0:a80552d32b80 361 bool Adafruit_BLE::writeNVM(uint16_t offset, uint8_t const data[], uint16_t size)
ajp109 0:a80552d32b80 362 {
ajp109 0:a80552d32b80 363 VERIFY_(offset + size <= NVM_USERDATA_SIZE );
ajp109 0:a80552d32b80 364
ajp109 0:a80552d32b80 365 uint16_t type[] = { AT_ARGTYPE_UINT16, AT_ARGTYPE_UINT8, (uint16_t) (AT_ARGTYPE_BYTEARRAY + size) };
ajp109 0:a80552d32b80 366 uint32_t args[] = { offset, BLE_DATATYPE_BYTEARRAY, (uint32_t) data };
ajp109 0:a80552d32b80 367
ajp109 0:a80552d32b80 368 return this->atcommand_full(F("AT+NVMWRITE"), NULL, 3, type, args);
ajp109 0:a80552d32b80 369 }
ajp109 0:a80552d32b80 370
ajp109 0:a80552d32b80 371 /******************************************************************************/
ajp109 0:a80552d32b80 372 /*!
ajp109 0:a80552d32b80 373 @brief Save String to NVM section, current size limit is 256 bytes
ajp109 0:a80552d32b80 374 @param data buffer holding data
ajp109 0:a80552d32b80 375 @param size number of bytes
ajp109 0:a80552d32b80 376 @param offset relative offset in the NVM section
ajp109 0:a80552d32b80 377 */
ajp109 0:a80552d32b80 378 /******************************************************************************/
ajp109 0:a80552d32b80 379 bool Adafruit_BLE::writeNVM(uint16_t offset, char const* str)
ajp109 0:a80552d32b80 380 {
ajp109 0:a80552d32b80 381 VERIFY_(offset + strlen(str) <= NVM_USERDATA_SIZE );
ajp109 0:a80552d32b80 382
ajp109 0:a80552d32b80 383 uint16_t type[] = { AT_ARGTYPE_UINT16, AT_ARGTYPE_UINT8, AT_ARGTYPE_STRING };
ajp109 0:a80552d32b80 384 uint32_t args[] = { offset, BLE_DATATYPE_STRING, (uint32_t) str };
ajp109 0:a80552d32b80 385
ajp109 0:a80552d32b80 386 return this->atcommand_full(F("AT+NVMWRITE"), NULL, 3, type, args);
ajp109 0:a80552d32b80 387 }
ajp109 0:a80552d32b80 388
ajp109 0:a80552d32b80 389 /******************************************************************************/
ajp109 0:a80552d32b80 390 /*!
ajp109 0:a80552d32b80 391 @brief Save an 32-bit number to NVM
ajp109 0:a80552d32b80 392 @param number Number to be saved
ajp109 0:a80552d32b80 393 @param offset relative offset in the NVM section
ajp109 0:a80552d32b80 394 */
ajp109 0:a80552d32b80 395 /******************************************************************************/
ajp109 0:a80552d32b80 396 bool Adafruit_BLE::writeNVM(uint16_t offset, int32_t number)
ajp109 0:a80552d32b80 397 {
ajp109 0:a80552d32b80 398 VERIFY_(offset + 4 <= NVM_USERDATA_SIZE );
ajp109 0:a80552d32b80 399
ajp109 0:a80552d32b80 400 uint16_t type[] = { AT_ARGTYPE_UINT16, AT_ARGTYPE_UINT8, AT_ARGTYPE_INT32 };
ajp109 0:a80552d32b80 401 uint32_t args[] = { offset, BLE_DATATYPE_INTEGER, (uint32_t) number };
ajp109 0:a80552d32b80 402
ajp109 0:a80552d32b80 403 return this->atcommand_full(F("AT+NVMWRITE"), NULL, 3, type, args);
ajp109 0:a80552d32b80 404 }
ajp109 0:a80552d32b80 405
ajp109 0:a80552d32b80 406 /******************************************************************************/
ajp109 0:a80552d32b80 407 /*!
ajp109 0:a80552d32b80 408 @brief Read an number of bytes from NVM at offset to buffer
ajp109 0:a80552d32b80 409 @param
ajp109 0:a80552d32b80 410 */
ajp109 0:a80552d32b80 411 /******************************************************************************/
ajp109 0:a80552d32b80 412 bool Adafruit_BLE::readNVM(uint16_t offset, uint8_t data[], uint16_t size)
ajp109 0:a80552d32b80 413 {
ajp109 0:a80552d32b80 414 VERIFY_(offset < NVM_USERDATA_SIZE);
ajp109 0:a80552d32b80 415
ajp109 0:a80552d32b80 416 uint8_t current_mode = _mode;
ajp109 0:a80552d32b80 417
ajp109 0:a80552d32b80 418 // switch mode if necessary to execute command
ajp109 0:a80552d32b80 419 if ( current_mode == BLUEFRUIT_MODE_DATA ) setMode(BLUEFRUIT_MODE_COMMAND);
ajp109 0:a80552d32b80 420
ajp109 0:a80552d32b80 421 // use RAW command version
ajp109 0:a80552d32b80 422 this->printf( "AT+NVMREADRAW=%hu,%hu", offset, size );
ajp109 0:a80552d32b80 423
ajp109 0:a80552d32b80 424 uint16_t len = readraw(); // readraw swallow OK/ERROR already
ajp109 0:a80552d32b80 425
ajp109 0:a80552d32b80 426 // Check for an error reading
ajp109 0:a80552d32b80 427 if ( len != size ) return false;
ajp109 0:a80552d32b80 428
ajp109 0:a80552d32b80 429 // skip if NULL is entered
ajp109 0:a80552d32b80 430 if (data) memcpy(data, this->buffer, min(size, BLE_BUFSIZE));
ajp109 0:a80552d32b80 431
ajp109 0:a80552d32b80 432 // switch back if necessary
ajp109 0:a80552d32b80 433 if ( current_mode == BLUEFRUIT_MODE_DATA ) setMode(BLUEFRUIT_MODE_DATA);
ajp109 0:a80552d32b80 434
ajp109 0:a80552d32b80 435 return true;
ajp109 0:a80552d32b80 436 }
ajp109 0:a80552d32b80 437
ajp109 0:a80552d32b80 438 /******************************************************************************/
ajp109 0:a80552d32b80 439 /*!
ajp109 0:a80552d32b80 440 @brief Read a string from NVM at offset to buffer
ajp109 0:a80552d32b80 441 @param
ajp109 0:a80552d32b80 442 */
ajp109 0:a80552d32b80 443 /******************************************************************************/
ajp109 0:a80552d32b80 444 bool Adafruit_BLE::readNVM(uint16_t offset, char* str, uint16_t size)
ajp109 0:a80552d32b80 445 {
ajp109 0:a80552d32b80 446 VERIFY_(offset < NVM_USERDATA_SIZE);
ajp109 0:a80552d32b80 447
ajp109 0:a80552d32b80 448 uint16_t type[] = { AT_ARGTYPE_UINT16, AT_ARGTYPE_UINT16, AT_ARGTYPE_UINT8 };
ajp109 0:a80552d32b80 449 uint32_t args[] = { offset, size, BLE_DATATYPE_STRING};
ajp109 0:a80552d32b80 450
ajp109 0:a80552d32b80 451 bool isOK = this->atcommand_full(F("AT+NVMREAD"), NULL, 3, type, args);
ajp109 0:a80552d32b80 452
ajp109 0:a80552d32b80 453 // skip if NULL is entered
ajp109 0:a80552d32b80 454 if ( isOK && str ) strncpy(str, this->buffer, min(size, BLE_BUFSIZE));
ajp109 0:a80552d32b80 455
ajp109 0:a80552d32b80 456 return isOK;
ajp109 0:a80552d32b80 457 }
ajp109 0:a80552d32b80 458
ajp109 0:a80552d32b80 459 /******************************************************************************/
ajp109 0:a80552d32b80 460 /*!
ajp109 0:a80552d32b80 461 @brief Read an 32-bit number from NVM
ajp109 0:a80552d32b80 462 @param
ajp109 0:a80552d32b80 463 */
ajp109 0:a80552d32b80 464 /******************************************************************************/
ajp109 0:a80552d32b80 465 bool Adafruit_BLE::readNVM(uint16_t offset, int32_t* number)
ajp109 0:a80552d32b80 466 {
ajp109 0:a80552d32b80 467 return this->readNVM(offset, (uint8_t*)number, 4);
ajp109 0:a80552d32b80 468 }
ajp109 0:a80552d32b80 469
ajp109 0:a80552d32b80 470 /**
ajp109 0:a80552d32b80 471 *
ajp109 0:a80552d32b80 472 * @param buffer
ajp109 0:a80552d32b80 473 * @param size
ajp109 0:a80552d32b80 474 * @return
ajp109 0:a80552d32b80 475 */
ajp109 0:a80552d32b80 476 int Adafruit_BLE::writeBLEUart(uint8_t const * buffer, int size)
ajp109 0:a80552d32b80 477 {
ajp109 0:a80552d32b80 478 uint8_t current_mode = _mode;
ajp109 0:a80552d32b80 479
ajp109 0:a80552d32b80 480 // switch mode if necessary to execute command
ajp109 0:a80552d32b80 481 if ( current_mode == BLUEFRUIT_MODE_COMMAND ) setMode(BLUEFRUIT_MODE_DATA);
ajp109 0:a80552d32b80 482
ajp109 0:a80552d32b80 483 size_t n = write(buffer, size);
ajp109 0:a80552d32b80 484
ajp109 0:a80552d32b80 485 // switch back if necessary
ajp109 0:a80552d32b80 486 if ( current_mode == BLUEFRUIT_MODE_COMMAND ) setMode(BLUEFRUIT_MODE_COMMAND);
ajp109 0:a80552d32b80 487
ajp109 0:a80552d32b80 488 return n;
ajp109 0:a80552d32b80 489 }
ajp109 0:a80552d32b80 490
ajp109 0:a80552d32b80 491 /**
ajp109 0:a80552d32b80 492 *
ajp109 0:a80552d32b80 493 * @param buffer
ajp109 0:a80552d32b80 494 * @param size
ajp109 0:a80552d32b80 495 * @return
ajp109 0:a80552d32b80 496 */
ajp109 0:a80552d32b80 497 int Adafruit_BLE::readBLEUart(uint8_t* buffer, int size)
ajp109 0:a80552d32b80 498 {
ajp109 0:a80552d32b80 499 uint8_t current_mode = _mode;
ajp109 0:a80552d32b80 500
ajp109 0:a80552d32b80 501 // switch mode if necessary to execute command
ajp109 0:a80552d32b80 502 if ( current_mode == BLUEFRUIT_MODE_COMMAND ) setMode(BLUEFRUIT_MODE_DATA);
ajp109 0:a80552d32b80 503
ajp109 0:a80552d32b80 504 size_t n = read(buffer, size);
ajp109 0:a80552d32b80 505
ajp109 0:a80552d32b80 506 // switch back if necessary
ajp109 0:a80552d32b80 507 if ( current_mode == BLUEFRUIT_MODE_COMMAND ) setMode(BLUEFRUIT_MODE_COMMAND);
ajp109 0:a80552d32b80 508
ajp109 0:a80552d32b80 509 return n;
ajp109 0:a80552d32b80 510 }
ajp109 0:a80552d32b80 511
ajp109 0:a80552d32b80 512 /******************************************************************************/
ajp109 0:a80552d32b80 513 /*!
ajp109 0:a80552d32b80 514 @brief Set handle for connect callback
ajp109 0:a80552d32b80 515
ajp109 0:a80552d32b80 516 @param[in] fp function pointer, NULL will discard callback
ajp109 0:a80552d32b80 517 */
ajp109 0:a80552d32b80 518 /******************************************************************************/
ajp109 0:a80552d32b80 519 void Adafruit_BLE::setConnectCallback( void (*fp) (void) )
ajp109 0:a80552d32b80 520 {
ajp109 0:a80552d32b80 521 this->_connect_callback = fp;
ajp109 0:a80552d32b80 522 install_callback(fp != NULL, EVENT_SYSTEM_CONNECT, -1);
ajp109 0:a80552d32b80 523 }
ajp109 0:a80552d32b80 524
ajp109 0:a80552d32b80 525 /******************************************************************************/
ajp109 0:a80552d32b80 526 /*!
ajp109 0:a80552d32b80 527 @brief Set handle for disconnection callback
ajp109 0:a80552d32b80 528
ajp109 0:a80552d32b80 529 @param[in] fp function pointer, NULL will discard callback
ajp109 0:a80552d32b80 530 */
ajp109 0:a80552d32b80 531 /******************************************************************************/
ajp109 0:a80552d32b80 532 void Adafruit_BLE::setDisconnectCallback( void (*fp) (void) )
ajp109 0:a80552d32b80 533 {
ajp109 0:a80552d32b80 534 this->_disconnect_callback = fp;
ajp109 0:a80552d32b80 535 install_callback(fp != NULL, EVENT_SYSTEM_DISCONNECT, -1);
ajp109 0:a80552d32b80 536 }
ajp109 0:a80552d32b80 537
ajp109 0:a80552d32b80 538 /******************************************************************************/
ajp109 0:a80552d32b80 539 /*!
ajp109 0:a80552d32b80 540 @brief Set handle for BLE Uart Rx callback
ajp109 0:a80552d32b80 541
ajp109 0:a80552d32b80 542 @param[in] fp function pointer, NULL will discard callback
ajp109 0:a80552d32b80 543 */
ajp109 0:a80552d32b80 544 /******************************************************************************/
ajp109 0:a80552d32b80 545 void Adafruit_BLE::setBleUartRxCallback( void (*fp) (char data[], uint16_t len) )
ajp109 0:a80552d32b80 546 {
ajp109 0:a80552d32b80 547 this->_ble_uart_rx_callback = fp;
ajp109 0:a80552d32b80 548 install_callback(fp != NULL, EVENT_SYSTEM_BLE_UART_RX, -1);
ajp109 0:a80552d32b80 549 }
ajp109 0:a80552d32b80 550
ajp109 0:a80552d32b80 551 /******************************************************************************/
ajp109 0:a80552d32b80 552 /*!
ajp109 0:a80552d32b80 553 @brief Set handle for BLE Gatt Rx callback
ajp109 0:a80552d32b80 554
ajp109 0:a80552d32b80 555 @param[in] fp function pointer, NULL will discard callback
ajp109 0:a80552d32b80 556 */
ajp109 0:a80552d32b80 557 /******************************************************************************/
ajp109 0:a80552d32b80 558 void Adafruit_BLE::setBleGattRxCallback(int32_t chars_idx, void (*fp) (int32_t, uint8_t[], uint16_t) )
ajp109 0:a80552d32b80 559 {
ajp109 0:a80552d32b80 560 if ( chars_idx == 0) return;
ajp109 0:a80552d32b80 561
ajp109 0:a80552d32b80 562 this->_ble_gatt_rx_callback = fp;
ajp109 0:a80552d32b80 563 install_callback(fp != NULL, -1, chars_idx-1);
ajp109 0:a80552d32b80 564 }
ajp109 0:a80552d32b80 565