Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FatFileSystem TB6612FNG2 mbed
Fork of JBB_BTLE_Test by
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 }
Generated on Tue Jul 12 2022 15:52:44 by
1.7.2
