![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
This is a demo for controlling your ShieldBot using your mobile phone
Dependencies: BLE_API ShieldBot_v12 mbed nRF51822
Fork of BLE_LoopbackUART by
main.cpp@0:e910d9bb040f, 2014-05-26 (annotated)
- Committer:
- yihui
- Date:
- Mon May 26 06:58:45 2014 +0000
- Revision:
- 0:e910d9bb040f
- Child:
- 2:e060367b9024
initial
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
yihui | 0:e910d9bb040f | 1 | /* mbed Microcontroller Library |
yihui | 0:e910d9bb040f | 2 | * Copyright (c) 2006-2013 ARM Limited |
yihui | 0:e910d9bb040f | 3 | * |
yihui | 0:e910d9bb040f | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
yihui | 0:e910d9bb040f | 5 | * you may not use this file except in compliance with the License. |
yihui | 0:e910d9bb040f | 6 | * You may obtain a copy of the License at |
yihui | 0:e910d9bb040f | 7 | * |
yihui | 0:e910d9bb040f | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
yihui | 0:e910d9bb040f | 9 | * |
yihui | 0:e910d9bb040f | 10 | * Unless required by applicable law or agreed to in writing, software |
yihui | 0:e910d9bb040f | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
yihui | 0:e910d9bb040f | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
yihui | 0:e910d9bb040f | 13 | * See the License for the specific language governing permissions and |
yihui | 0:e910d9bb040f | 14 | * limitations under the License. |
yihui | 0:e910d9bb040f | 15 | */ |
yihui | 0:e910d9bb040f | 16 | |
yihui | 0:e910d9bb040f | 17 | #include "mbed.h" |
yihui | 0:e910d9bb040f | 18 | #include "nRF51822n.h" |
yihui | 0:e910d9bb040f | 19 | |
yihui | 0:e910d9bb040f | 20 | #define BLE_UUID_NUS_SERVICE 0x0001 /**< The UUID of the Nordic UART Service. */ |
yihui | 0:e910d9bb040f | 21 | #define BLE_UUID_NUS_TX_CHARACTERISTIC 0x0002 /**< The UUID of the TX Characteristic. */ |
yihui | 0:e910d9bb040f | 22 | #define BLE_UUID_NUS_RX_CHARACTERISTIC 0x0003 /**< The UUID of the RX Characteristic. */ |
yihui | 0:e910d9bb040f | 23 | |
yihui | 0:e910d9bb040f | 24 | #ifdef DEBUG |
yihui | 0:e910d9bb040f | 25 | #define LOG(args...) pc.printf(args) |
yihui | 0:e910d9bb040f | 26 | |
yihui | 0:e910d9bb040f | 27 | Serial pc(USBTX, USBRX); |
yihui | 0:e910d9bb040f | 28 | #else |
yihui | 0:e910d9bb040f | 29 | #define LOG(args...) |
yihui | 0:e910d9bb040f | 30 | #endif |
yihui | 0:e910d9bb040f | 31 | |
yihui | 0:e910d9bb040f | 32 | nRF51822n nrf; /* BLE radio driver */ |
yihui | 0:e910d9bb040f | 33 | |
yihui | 0:e910d9bb040f | 34 | DigitalOut led1(p1); |
yihui | 0:e910d9bb040f | 35 | DigitalOut advertisingStateLed(p30); |
yihui | 0:e910d9bb040f | 36 | |
yihui | 0:e910d9bb040f | 37 | // The Nordic UART Service |
yihui | 0:e910d9bb040f | 38 | uint8_t uart_base_uuid[] = {0x6e, 0x40, 0x01, 0x00, 0xb5, 0xa3, 0xf3, 0x93, 0xe0, 0xa9, 0xe5,0x0e, 0x24, 0xdc, 0xca, 0x9e}; |
yihui | 0:e910d9bb040f | 39 | uint8_t txPayload[8] = {0,}; |
yihui | 0:e910d9bb040f | 40 | uint8_t rxPayload[8] = {0,}; |
yihui | 0:e910d9bb040f | 41 | GattService uartService (uart_base_uuid); |
yihui | 0:e910d9bb040f | 42 | GattCharacteristic txCharacteristic (BLE_UUID_NUS_TX_CHARACTERISTIC, 1, 8, |
yihui | 0:e910d9bb040f | 43 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE); |
yihui | 0:e910d9bb040f | 44 | GattCharacteristic rxCharacteristic (BLE_UUID_NUS_RX_CHARACTERISTIC, 1, 8, |
yihui | 0:e910d9bb040f | 45 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); |
yihui | 0:e910d9bb040f | 46 | |
yihui | 0:e910d9bb040f | 47 | /* Advertising data and parameters */ |
yihui | 0:e910d9bb040f | 48 | GapAdvertisingData advData; |
yihui | 0:e910d9bb040f | 49 | GapAdvertisingData scanResponse; |
yihui | 0:e910d9bb040f | 50 | GapAdvertisingParams advParams ( GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED ); |
yihui | 0:e910d9bb040f | 51 | |
yihui | 0:e910d9bb040f | 52 | uint16_t uuid16_list[] = {BLE_UUID_NUS_SERVICE}; |
yihui | 0:e910d9bb040f | 53 | |
yihui | 0:e910d9bb040f | 54 | /**************************************************************************/ |
yihui | 0:e910d9bb040f | 55 | /*! |
yihui | 0:e910d9bb040f | 56 | @brief This custom class can be used to override any GapEvents |
yihui | 0:e910d9bb040f | 57 | that you are interested in handling on an application level. |
yihui | 0:e910d9bb040f | 58 | */ |
yihui | 0:e910d9bb040f | 59 | /**************************************************************************/ |
yihui | 0:e910d9bb040f | 60 | class GapEventHandler : public GapEvents |
yihui | 0:e910d9bb040f | 61 | { |
yihui | 0:e910d9bb040f | 62 | //virtual void onTimeout(void) {} |
yihui | 0:e910d9bb040f | 63 | |
yihui | 0:e910d9bb040f | 64 | virtual void onConnected(void) { |
yihui | 0:e910d9bb040f | 65 | advertisingStateLed = 0; |
yihui | 0:e910d9bb040f | 66 | LOG("Connected!\n\r"); |
yihui | 0:e910d9bb040f | 67 | } |
yihui | 0:e910d9bb040f | 68 | |
yihui | 0:e910d9bb040f | 69 | /* When a client device disconnects we need to start advertising again. */ |
yihui | 0:e910d9bb040f | 70 | virtual void onDisconnected(void) { |
yihui | 0:e910d9bb040f | 71 | nrf.getGap().startAdvertising(advParams); |
yihui | 0:e910d9bb040f | 72 | advertisingStateLed = 1; |
yihui | 0:e910d9bb040f | 73 | LOG("Disconnected!\n\r"); |
yihui | 0:e910d9bb040f | 74 | LOG("Restarting the advertising process\n\r"); |
yihui | 0:e910d9bb040f | 75 | } |
yihui | 0:e910d9bb040f | 76 | }; |
yihui | 0:e910d9bb040f | 77 | |
yihui | 0:e910d9bb040f | 78 | /**************************************************************************/ |
yihui | 0:e910d9bb040f | 79 | /*! |
yihui | 0:e910d9bb040f | 80 | @brief This custom class can be used to override any GattServerEvents |
yihui | 0:e910d9bb040f | 81 | that you are interested in handling on an application level. |
yihui | 0:e910d9bb040f | 82 | */ |
yihui | 0:e910d9bb040f | 83 | /**************************************************************************/ |
yihui | 0:e910d9bb040f | 84 | class GattServerEventHandler : public GattServerEvents |
yihui | 0:e910d9bb040f | 85 | { |
yihui | 0:e910d9bb040f | 86 | virtual void onDataSent(uint16_t charHandle) { |
yihui | 0:e910d9bb040f | 87 | if (charHandle == txCharacteristic.handle) { |
yihui | 0:e910d9bb040f | 88 | LOG("onDataSend()\n\r"); |
yihui | 0:e910d9bb040f | 89 | |
yihui | 0:e910d9bb040f | 90 | } |
yihui | 0:e910d9bb040f | 91 | } |
yihui | 0:e910d9bb040f | 92 | |
yihui | 0:e910d9bb040f | 93 | virtual void onDataWritten(uint16_t charHandle) { |
yihui | 0:e910d9bb040f | 94 | if (charHandle == txCharacteristic.handle) { |
yihui | 0:e910d9bb040f | 95 | LOG("onDataWritten()\n\r"); |
yihui | 0:e910d9bb040f | 96 | nrf.getGattServer().readValue(txCharacteristic.handle, txPayload, 8); // Current APIs don't provide the length of the payload |
yihui | 0:e910d9bb040f | 97 | LOG("ECHO: %s\n\r", (char *)txPayload); |
yihui | 0:e910d9bb040f | 98 | nrf.getGattServer().updateValue(rxCharacteristic.handle, txPayload, 8); |
yihui | 0:e910d9bb040f | 99 | } |
yihui | 0:e910d9bb040f | 100 | } |
yihui | 0:e910d9bb040f | 101 | |
yihui | 0:e910d9bb040f | 102 | virtual void onUpdatesEnabled(uint16_t charHandle) { |
yihui | 0:e910d9bb040f | 103 | LOG("onUpdateEnabled\n\r"); |
yihui | 0:e910d9bb040f | 104 | } |
yihui | 0:e910d9bb040f | 105 | |
yihui | 0:e910d9bb040f | 106 | virtual void onUpdatesDisabled(uint16_t charHandle) { |
yihui | 0:e910d9bb040f | 107 | LOG("onUpdatesDisabled\n\r"); |
yihui | 0:e910d9bb040f | 108 | } |
yihui | 0:e910d9bb040f | 109 | |
yihui | 0:e910d9bb040f | 110 | //virtual void onConfirmationReceived(uint16_t charHandle) {} |
yihui | 0:e910d9bb040f | 111 | }; |
yihui | 0:e910d9bb040f | 112 | |
yihui | 0:e910d9bb040f | 113 | /**************************************************************************/ |
yihui | 0:e910d9bb040f | 114 | /*! |
yihui | 0:e910d9bb040f | 115 | @brief Program entry point |
yihui | 0:e910d9bb040f | 116 | */ |
yihui | 0:e910d9bb040f | 117 | /**************************************************************************/ |
yihui | 0:e910d9bb040f | 118 | int main(void) |
yihui | 0:e910d9bb040f | 119 | { |
yihui | 0:e910d9bb040f | 120 | |
yihui | 0:e910d9bb040f | 121 | /* Setup an event handler for GAP events i.e. Client/Server connection events. */ |
yihui | 0:e910d9bb040f | 122 | nrf.getGap().setEventHandler(new GapEventHandler()); |
yihui | 0:e910d9bb040f | 123 | nrf.getGattServer().setEventHandler(new GattServerEventHandler()); |
yihui | 0:e910d9bb040f | 124 | |
yihui | 0:e910d9bb040f | 125 | /* Initialise the nRF51822 */ |
yihui | 0:e910d9bb040f | 126 | nrf.init(); |
yihui | 0:e910d9bb040f | 127 | |
yihui | 0:e910d9bb040f | 128 | /* Make sure we get a clean start */ |
yihui | 0:e910d9bb040f | 129 | nrf.reset(); |
yihui | 0:e910d9bb040f | 130 | |
yihui | 0:e910d9bb040f | 131 | /* Add BLE-Only flag and complete service list to the advertising data */ |
yihui | 0:e910d9bb040f | 132 | advData.addFlags(GapAdvertisingData::BREDR_NOT_SUPPORTED); |
yihui | 0:e910d9bb040f | 133 | advData.addData(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, |
yihui | 0:e910d9bb040f | 134 | (uint8_t*)uuid16_list, sizeof(uuid16_list)); |
yihui | 0:e910d9bb040f | 135 | |
yihui | 0:e910d9bb040f | 136 | advData.addData(GapAdvertisingData::SHORTENED_LOCAL_NAME, |
yihui | 0:e910d9bb040f | 137 | (uint8_t*)"BLE UART", sizeof("BLE UART") - 1); |
yihui | 0:e910d9bb040f | 138 | |
yihui | 0:e910d9bb040f | 139 | advData.addAppearance(GapAdvertisingData::UNKNOWN); |
yihui | 0:e910d9bb040f | 140 | nrf.getGap().setAdvertisingData(advData, scanResponse); |
yihui | 0:e910d9bb040f | 141 | |
yihui | 0:e910d9bb040f | 142 | /* UART Service */ |
yihui | 0:e910d9bb040f | 143 | uartService.addCharacteristic(rxCharacteristic); |
yihui | 0:e910d9bb040f | 144 | uartService.addCharacteristic(txCharacteristic); |
yihui | 0:e910d9bb040f | 145 | nrf.getGattServer().addService(uartService); |
yihui | 0:e910d9bb040f | 146 | |
yihui | 0:e910d9bb040f | 147 | /* Start advertising (make sure you've added all your data first) */ |
yihui | 0:e910d9bb040f | 148 | nrf.getGap().startAdvertising(advParams); |
yihui | 0:e910d9bb040f | 149 | |
yihui | 0:e910d9bb040f | 150 | advertisingStateLed = 1; |
yihui | 0:e910d9bb040f | 151 | |
yihui | 0:e910d9bb040f | 152 | /* Do blinky on LED1 while we're waiting for BLE events */ |
yihui | 0:e910d9bb040f | 153 | for (;;) { |
yihui | 0:e910d9bb040f | 154 | led1 = !led1; |
yihui | 0:e910d9bb040f | 155 | wait(1); |
yihui | 0:e910d9bb040f | 156 | } |
yihui | 0:e910d9bb040f | 157 | } |