Junichi Katsu / Mbed 2 deprecated JBB_BTLE_Test

Dependencies:   FatFileSystem TB6612FNG2 mbed

Fork of JBB_BTLE_Test by Jksoft Blue mbed Board Developer

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BLE_demo.cpp Source File

BLE_demo.cpp

00001 /*
00002  * Copyright (C) 2011-2012 by Matthias Ringwald
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  * 4. This software may not be used in a commercial product
00017  *    without an explicit license granted by the copyright holder.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
00020  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00022  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
00023  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00024  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00025  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00026  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00027  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00028  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00029  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00030  * SUCH DAMAGE.
00031  *
00032  */
00033 
00034 /*  Change history
00035  2013/2/10: by todotani
00036   Modified tick event handler
00037   Modified LED control
00038   - LED 3 flush when connected
00039   - LED 2 OFF in case write attribute, ON in case read attribute
00040   - LED 1 OFF of after start of advertisement, then reflect write value to 0xFFF2
00041 2013/2/11: by todotani
00042   Changed serial pc.baud (115200 to 921600) to avoid imcomplete connection issue
00043   Disable btstack debug-log
00044 2013/2/20: by todotani
00045   Change tick timer interval 250ms to 1ms
00046   Change Attribute 0xFFF1 as read DigitalIn p5 of mbed
00047 */
00048 
00049 //*****************************************************************************
00050 //
00051 // att device demo
00052 //
00053 //*****************************************************************************
00054 
00055 // TODO: seperate BR/EDR from LE ACL buffers
00056 // TODO: move LE init into HCI
00057 // ..
00058 
00059 // NOTE: Supports only a single connection
00060 
00061 // mbed specific
00062 #include "mbed.h"
00063 Serial pc(USBTX, USBRX);
00064 DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);;
00065 DigitalIn  sw1(p5);
00066 
00067 // from btstack ble_server.c
00068 #include "global.h"
00069 #include "debug.h"
00070 #include "btstack/btstack.h"
00071 #include "btstack/hci_cmds.h"
00072 #include "btstack/run_loop.h"
00073 #include "btstack/hal_tick.h"
00074 
00075 #include "hci.h"
00076 #include "l2cap.h"
00077 #include "btstack_memory.h"
00078 #include "remote_device_db.h"
00079 #include "config.h"
00080 
00081 #include "att.h"
00082 #include "TB6612.h"
00083 
00084 TB6612 MOTOR_A(p21,p19,p20);            // PWM IN1 IN2
00085 TB6612 MOTOR_B(p22,p29,p30);            // PWM IN1 IN2
00086 
00087 hci_transport_t * hci_transport_picusb_instance();
00088 
00089 static att_connection_t att_connection;
00090 static uint16_t         att_response_handle = 0;
00091 static uint16_t         att_response_size   = 0;
00092 static uint8_t          att_response_buffer[28];
00093 
00094 static uint8_t          switch_new_state   = 1;
00095 static uint8_t          switch_old_state   = 1;
00096 
00097 void hexdump2(void *data, int size)
00098 {
00099     int i;
00100     for (i=0; i<size; i++) {
00101         log_info("%02X ", ((uint8_t *)data)[i]);
00102     }
00103     log_info("\n");
00104 }
00105 
00106 static void att_try_respond(void)
00107 {
00108     if (!att_response_size) return;
00109     if (!att_response_handle) return;
00110     if (!hci_can_send_packet_now(HCI_ACL_DATA_PACKET)) return;
00111 
00112     // update state before sending packet
00113     uint16_t size = att_response_size;
00114     att_response_size = 0;
00115     l2cap_send_connectionless(att_response_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, att_response_buffer, size);
00116 }
00117 
00118 
00119 static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size)
00120 {
00121     if (packet_type != ATT_DATA_PACKET) return;
00122 
00123     att_response_handle = handle;
00124     att_response_size = att_handle_request(&att_connection, packet, size, att_response_buffer);
00125     att_try_respond();
00126 }
00127 
00128 
00129 // enable LE, setup ADV data
00130 static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
00131 {
00132     static bd_addr_t addr;
00133     // Data for advertisement and scan response
00134     const uint8_t adv_data[31]="\x02\x01\x05" "\x05\x09mbed" "\x03\x02\xf0\xff";
00135     switch (packet_type) {
00136 
00137         case HCI_EVENT_PACKET:
00138             switch (packet[0]) {
00139 
00140                 case BTSTACK_EVENT_STATE:
00141                     // bt stack activated, get started - set local name
00142                     if (packet[2] == HCI_STATE_WORKING) {
00143                         log_info("Working!\n");
00144                         hci_send_cmd(&hci_read_local_supported_features);
00145                     }
00146                     break;
00147 
00148                 case DAEMON_EVENT_HCI_PACKET_SENT:
00149                     att_try_respond();
00150                     break;
00151 
00152                 case HCI_EVENT_LE_META:
00153                     switch (packet[2]) {
00154                         case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
00155                             // reset connection MTU
00156                             att_connection.mtu = 23;
00157                             break;
00158                         default:
00159                             break;
00160                     }
00161                     break;
00162 
00163                 case BTSTACK_EVENT_NR_CONNECTIONS_CHANGED:
00164                     if (packet[2]) {
00165                         connection_status=1;
00166                         log_info("CONNECTED\n");
00167                     } else {
00168                         connection_status=0;
00169                         log_info("NOT CONNECTED\n");
00170                     }
00171                     break;
00172 
00173                 case HCI_EVENT_DISCONNECTION_COMPLETE:
00174                     att_response_handle =0;
00175                     att_response_size = 0;
00176 
00177                     // restart advertising
00178                     hci_send_cmd(&hci_le_set_advertise_enable, 1);
00179                     break;
00180 
00181                 case HCI_EVENT_COMMAND_COMPLETE:
00182                     if (COMMAND_COMPLETE_EVENT(packet, hci_read_bd_addr)) {
00183                         bt_flip_addr(addr, &packet[6]);
00184                         log_info("BD ADDR: %s\n", bd_addr_to_str(addr));
00185                         break;
00186                     }
00187                     if (COMMAND_COMPLETE_EVENT(packet, hci_read_local_supported_features)) {
00188                         log_info("Local supported features: %04lX%04lX\n", READ_BT_32(packet, 10), READ_BT_32(packet, 6));
00189                         hci_send_cmd(&hci_set_event_mask, 0xffffffff, 0x20001fff);
00190                         break;
00191                     }
00192                     if (COMMAND_COMPLETE_EVENT(packet, hci_set_event_mask)) {
00193                         hci_send_cmd(&hci_write_le_host_supported, 1, 1);
00194                         break;
00195                     }
00196                     if (COMMAND_COMPLETE_EVENT(packet, hci_write_le_host_supported)) {
00197                         hci_send_cmd(&hci_le_set_event_mask, 0xffffffff, 0xffffffff);
00198                         break;
00199                     }
00200                     if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_event_mask)) {
00201                         hci_send_cmd(&hci_le_read_buffer_size);
00202                         break;
00203                     }
00204                     if (COMMAND_COMPLETE_EVENT(packet, hci_le_read_buffer_size)) {
00205                         log_info("LE buffer size: %u, count %u\n", READ_BT_16(packet,6), packet[8]);
00206                         hci_send_cmd(&hci_le_read_supported_states);
00207                         break;
00208                     }
00209                     if (COMMAND_COMPLETE_EVENT(packet, hci_le_read_supported_states)) {
00210                         hci_send_cmd(&hci_le_set_advertising_parameters,  0x0400, 0x0800, 0, 0, 0, &addr, 0x07, 0);
00211                         break;
00212                     }
00213                     if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertising_parameters)) {
00214                         hci_send_cmd(&hci_le_set_advertising_data, sizeof(adv_data), adv_data);
00215                         break;
00216                     }
00217                     if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertising_data)) {
00218                         hci_send_cmd(&hci_le_set_scan_response_data, 10, adv_data);
00219                         break;
00220                     }
00221                     if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_scan_response_data)) {
00222                         hci_send_cmd(&hci_le_set_advertise_enable, 1);
00223                         break;
00224                     }
00225                     if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertise_enable)) {
00226                         hci_discoverable_control(1);
00227                         log_info("startup_state=1\n");
00228                         startup_state=1;
00229                         led1 = 0;
00230                         break;
00231                     }
00232 
00233             }
00234     }
00235 }
00236 
00237 // test profile
00238 #include "profile.h"
00239 
00240 static uint8_t strbuf[80];
00241 static uint8_t  ledvalue;
00242 
00243 // read requests
00244 static uint16_t att_read_callback(uint16_t handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size)
00245 {
00246     uint16_t    ret=0,val;
00247 
00248     if(buffer) {
00249         log_info("READ Callback, handle %04x\n", handle);
00250         led2 = 1;
00251     }
00252     switch(handle) {
00253             // Correspond to Characteristics 0xFFF1
00254         case 0x000b:
00255 #if 0
00256             if(buffer && ret<=buffer_size) {
00257                 buffer[0] = sw1.read();
00258                 log_info("Read value: %u\n", buffer[0]);
00259             }
00260             ret = 1;
00261 #else
00262             ret = 0;
00263 #endif
00264             break;
00265 
00266             // Correspond to Characteristics 0xFFF2
00267         case 0x000d:
00268             if(buffer && buffer_size) {
00269                 ledvalue = led1;
00270                 buffer[0] = ledvalue;
00271                 log_info("Read value: %u\n", buffer[0]);
00272             }
00273             ret=1;
00274             break;
00275 
00276             // Correspond to Characteristics 0x00001234-0000-1000-8000-00805F9B34FB
00277         case 0x000f:
00278             if(buffer && buffer_size>=2) {
00279                 val=timer_counter;
00280                 log_info("Read value: %u\n", val);
00281                 buffer[0]=val&0xff;
00282                 buffer[1]=val>>8;
00283             }
00284             ret=2;
00285             break;
00286     }
00287     return ret;
00288 }
00289 
00290 // write requests
00291 static void att_write_callback(uint16_t handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size, signature_t * signature)
00292 {
00293     log_info("WRITE Callback, handle %04x\n", handle);
00294     led2 = 0;
00295     switch(handle) {
00296             // Correspond to Characteristics 0xFFF1
00297         case 0x000b:
00298             uint16_t game_pad;
00299             game_pad = (buffer[0] << 8 ) | buffer[1];
00300             //log_info("No action\n");
00301             switch(game_pad)
00302             {
00303             case 0x0001:
00304                 MOTOR_A = 30;
00305                 MOTOR_B = 30;
00306                 break;
00307             case 0x0002:
00308                 MOTOR_A = -30;
00309                 MOTOR_B = -30;
00310                 break;
00311             case 0x0004:
00312                 MOTOR_A = 30;
00313                 MOTOR_B = -30;
00314                 break;
00315             case 0x0008:
00316                 MOTOR_A = -30;
00317                 MOTOR_B = 30;
00318                 break;
00319             case 0x0100:
00320                 led4 = !led4;
00321                 int x = (int)buffer[6] - 128;
00322                 if( (x > 5)||(x < -5) )
00323                 {
00324                     x = x > 100 ? 100 : x; 
00325                     x = x < -100 ? -100 : x; 
00326                     MOTOR_A = x > 0 ? 100 - x : 100;
00327                     MOTOR_B = x < 0 ? 100 + x : 100;
00328                 }
00329             default:
00330                 MOTOR_A = 0;
00331                 MOTOR_B = 0;
00332                 break;
00333             
00334             }
00335             break;
00336 
00337             // Correspond to Characteristics 0xFFF2
00338         case 0x000d:
00339             log_info("New value: %u\n", buffer[0]);
00340             ledvalue = buffer[0];
00341             led1 = ledvalue;
00342             break;
00343     }
00344 }
00345 
00346 
00347 void hal_tick_event(void)
00348 {
00349     timer_counter++;
00350 
00351     if(connection_status) {
00352         if(timer_counter % 250 == 0) {
00353             led3 = !led3;
00354             //  Under testing
00355             //            switch_new_state = (uint8_t)sw1.read();
00356             //            if (switch_new_state != switch_old_state) {
00357             //                log_info("Fire notification\n");
00358             //                switch_old_state = switch_new_state;
00359             //                att_prepare_handle_value_notification(&att_connection, 0x000b, &switch_new_state, 1, att_response_buffer);
00360         }
00361     } else {
00362         led3 = 1;
00363     }
00364 }
00365 
00366 // main
00367 int main(void)
00368 {
00369     pc.baud(921600);
00370     //pc.baud(230400);
00371     log_info("%s\n", __FILE__);
00372 
00373     // init LEDs
00374     led1 = led2 = led3 = 1;
00375     ledvalue = led1;
00376 
00377     /// GET STARTED with BTstack ///
00378     btstack_memory_init();
00379     run_loop_init(RUN_LOOP_EMBEDDED);
00380     hal_tick_set_handler(&hal_tick_event);
00381 
00382     // init HCI
00383     // use BlueUSB
00384     hci_transport_t* transport = hci_transport_usb_instance();
00385     bt_control_t       * control   = NULL;
00386     hci_uart_config_t  * config    = NULL;
00387     remote_device_db_t * remote_db = (remote_device_db_t *) &remote_device_db_memory;
00388     hci_init(transport, config, control, remote_db);
00389 
00390     // use eHCILL
00391     // bt_control_cc256x_enable_ehcill(1);
00392 
00393     // set up l2cap_le
00394     l2cap_init();
00395     l2cap_register_fixed_channel(att_packet_handler, L2CAP_CID_ATTRIBUTE_PROTOCOL);
00396     l2cap_register_packet_handler(packet_handler);
00397 
00398     // set up ATT
00399     att_set_db(profile_data);
00400     att_set_write_callback(att_write_callback);
00401     att_set_read_callback(att_read_callback);
00402     att_dump_attributes();
00403     att_connection.mtu = 27;
00404 
00405     log_info("Run...\n\n");
00406 
00407     // turn on!
00408     hci_power_control(HCI_POWER_ON);
00409 
00410     // go!
00411     run_loop_execute();
00412 
00413     // happy compiler!
00414     return 0;
00415 }